当前位置: 首页 > wzjs >正文

旅游网站建设论文网站建设公司大全

旅游网站建设论文,网站建设公司大全,网页上海公司,google站长工具直接内存 在 Java 中对象都是在堆内分配的,通常我们说的JVM 内存也就指的堆内内存,堆内内存完全被JVM 虚拟机所管理,JVM 有自己的垃圾回收算法,对于使用者来说不必关心对象的内存如何回收。堆外内存与堆内内存相对应,…

直接内存

在 Java 中对象都是在堆内分配的,通常我们说的JVM 内存也就指的堆内内存,堆内内存完全被JVM 虚拟机所管理,JVM 有自己的垃圾回收算法,对于使用者来说不必关心对象的内存如何回收。堆外内存与堆内内存相对应,对于整个机器内存而言,除堆内内存以外部分即为堆外内存。堆外内存不受 JVM 虚拟机管理,直接由操作系统管理。直接内存申请空间调用 allocateDirect() 方法就可以了。
Java 中堆外内存的分配方式有两种:ByteBuffer#allocateDirectUnsafe#allocateMemory
Java NIO 包中的 ByteBuffer 类的分配方式如下:

// 分配 10M 堆外内存ByteBuffer buffer = ByteBuffer.allocateDirect(10 * 1024 * 1024); 

下图展示了 Buffer 分配在直接内存的功能和作用:
image-20250317112327750

直接内存的好处是:Java 程序可以直接在内存上为 ByteBuffer 申请空间,而不是在 JVM 的堆空间上申请。如果我们在 JVM 申请空间,想保存到磁盘中,数据的拷贝路径是这样的:JVM 空间–>操作系统控制的内存–>磁盘。但如果我们在直接内存给 ByteBuffer 分配空间,那么数据的拷贝路径是:操作系统控制的直接内存–>磁盘。这样就少了一次数据拷贝次数,提高了效率。

当然,直接内存也是有劣势的,比如申请和释放直接内存的开销比 JVM 内存要大。

堆外内存怎么回收?

image-20250317191825781

堆内存放的 DirectByteBuffer 对象并不大,仅仅包含堆外内存的地址、大小等属性,同时还会创建对应的 Cleaner 对象,通过 ByteBuffer 分配的堆外内存不需要手动回收,它可以被 JVM 自动回收。当堆内的 DirectByteBuffer 对象被 GC 回收时,Cleaner 就会用于回收对应的堆外内存

试想这么一种场景,因为 DirectByteBuffer 对象有可能长时间存在于堆内内存,所以它很可能晋升到 JVM 的老年代,所以这时候 DirectByteBuffer 对象的回收需要依赖 Old GC 或者 Full GC 才能触发清理。如果长时间没有 Old GC 或者 Full GC 执行,那么堆外内存即使不再使用,也会一直在占用内存不释放,很容易将机器的物理内存耗尽,这是相当危险的。

那么在使用 DirectByteBuffer 时我们如何避免物理内存被耗尽呢?因为 JVM 并不知道堆外内存是不是已经不足了,所以我们最好通过 JVM 参数 -XX:MaxDirectMemorySize 指定堆外内存的上限大小,当堆外内存的大小超过该阈值时,就会触发一次 Full GC 进行清理回收,如果在 Full GC 之后还是无法满足堆外内存的分配,那么程序将会抛出 OOM 异常。

此外在 ByteBuffer.allocateDirect 分配的过程中,如果没有足够的空间分配堆外内存,在 Bits.reserveMemory 方法中也会主动调用 System.gc() 强制执行 Full GC,但是在生产环境一般都是设置了 -XX:+DisableExplicitGC,System.gc() 是不起作用的,所以依赖 System.gc() 并不是一个好办法。

通过前面堆外内存分配方式的介绍,可以知道 DirectByteBuffer 在初始化时会创建一个 Cleaner 对象,它会负责堆外内存的回收工作。Cleaner 就属于虚引用PhantomReference 的子类,虚引用唯一能做的是在对象被GC时,收到通知,并执行一些后续工作。如以下源码所示,PhantomReference 不能被单独使用,需要与引用队列 ReferenceQueue 联合使用。

public class Cleaner extends java.lang.ref.PhantomReference<java.lang.Object> {private static final java.lang.ref.ReferenceQueue<java.lang.Object> dummyQueue;private static sun.misc.Cleaner first;private sun.misc.Cleaner next;private sun.misc.Cleaner prev;private final java.lang.Runnable thunk;public void clean() {}}

当初始化堆外内存时,内存中的对象引用情况如下图所示,first 是 Cleaner 类中的静态变量,Cleaner 对象在初始化时会加入 Cleaner 链表中。DirectByteBuffer 对象包含堆外内存的地址、大小以及 Cleaner 对象的引用,ReferenceQueue 用于保存需要回收的 Cleaner 对象。

image-20250317192638529

当发生 GC 时,DirectByteBuffer 对象被回收,内存中的对象引用情况发生了如下变化:

image-20250317192655460

此时 Cleaner 对象不再有任何引用关系,在下一次 GC 时,该 Cleaner 对象将被添加到 ReferenceQueue 中,有一个后台任务会从这个队列中拿出对象并执行 clean() 方法。clean() 方法主要做两件事情:

  1. 将 Cleaner 对象从 Cleaner 链表中移除;
  2. 调用 unsafe.freeMemory 方法清理堆外内存。

四大引用

在Java层面,一共有四种引用:强引用、软引用、弱引用、虚引用,从名字也可以发现,这几种引用的生命周期由强到弱。

强引用

强引用(Strong Reference)是使用最普遍的引用,99%的代码可能都是强引用,很多人平时接触的也都是强引用相关的代码,比如下面这种:

Object o=new Object()

这种情况是普遍存在的,在写中间件框架代码时,可能才需要其它引用。

如果一个对象,和GC Root有强引用的关系,当内存不足发生GC时,宁可抛出OOM异常,终止程序,也不会回收这些对象。相反,当一个对象,和GC Root没有强引用关系时,可能会被回收(因为可能还有其它引用),如果没有任何引用关系,GC之后,该对象就被回收了。

软引用

如果一个对象只具有软引用(Soft Reference),则内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。这种特别适合用来实现缓存。

Object reference = new MyObject();
System.out.println(reference);
Reference root = new SoftReference(reference);
reference = null; // MyObject对象只有软引用
System.gc();
System.out.println(root.get());输出:
cn.itcast.nio.c10.MyObject@511d50c0
cn.itcast.nio.c10.MyObject@511d50c0

弱引用

弱引用(Weak Reference),相对于软引用,它的生命周期更短,当发生GC时,如果扫描到一个对象只有弱引用,不管当前内存是否足够,都会对它进行回收。

感觉说的有点干,来段代码解解渴。

Object reference = new MyObject();
System.out.println(reference);
Reference root = new WeakReference(reference);
reference = null; // MyObject对象只有弱引用
System.gc(); 
System.out.println(root.get());
输出:
null

ThreadLocal

scala 代码解读复制代码static class ThreadLocalMap {static class Entry extends WeakReference<ThreadLocal<?>> {Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}}//......}

ThreadLocal.ThreadLocalMap.Entry 继承了弱引用,key为当前线程实例,和WeakHashMap基本相同。

虚引用

虚引用(Phantom Reference),和之前两种引用的最大不同是:它的get方法一直返回null。

很奇怪,一个返回null的引用有什么用?

虚引用的使用场景很窄,在JDK中,目前只知道在申请堆外内存时有它的身影。 申请堆外内存时,在JVM堆中会创建一个对应的Cleaner对象,这个Cleaner类继承了PhantomReference,当DirectByteBuffer对象被回收时,可以执行对应的Cleaner对象的clean方法,做一些后续工作,这里是释放之前申请的堆外内存。

由于虚引用的get方法无法拿到真实对象,所以当你不想让真实对象被访问时,可以选择使用虚引用,它唯一能做的是在对象被GC时,收到通知,并执行一些后续工作。

实现原理

上述引用中,除了强引用,其它几种都有对应的实现类,都继承了Reference。

Reference有几个重要的参数,有些和GC密切相关:

  1. referent: 就是所引用的对象,会被GC特别对待。
  2. queue:RererenceQueue,看名字也知道它是一个Reference队列,用来保存Reference对象,当新建一个Reference时,可以选择性的传入第二个参数。
  3. discovered:该对象被JVM使用,表示下一个要被处理的Reference对象(1.8的实现)
  4. next:当Reference对象被放入RererenceQueue时,使用next变量形成链表结构。
  5. pending:该对象会被JVM使用,当前被处理的Reference对象。

Reference中有一个重要的线程 Reference Handler,运行优先级极高,启动之后负责轮询pending变量是否有数据,如果pending被JVM设置了一个值,就把它拿出来放到queue中,这里有个例外,就是之前说的堆外内存申请时的Cleaner对象,只会执行它的clean方法,并不会放到queue中。

当Reference对象被放进queue之后,就可以使用一个线程,依次拿出来进行处理。

  @Testpublic void test2() throws IOException {final ReferenceQueue queue = new ReferenceQueue();new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {Reference reference = queue.remove();System.out.println(reference + "回收了");} catch (InterruptedException e) {}}}}).start();Object o = new Object();Reference root = new WeakReference(o, queue);System.out.println(root);o = null;System.gc();System.in.read();}java.lang.ref.WeakReference@4c98385c
java.lang.ref.WeakReference@4c98385c回收了  

上述代码中,先初始化了一个ReferenceQueue,随后又初始化了一个线程,循环的从queue中捞数据,因为当一个软引用、弱引用或虚引用的对象被GC回收时,这个引用会被放到对应的ReferenceQueue中,这里会被拿出来进行打印,更多的是做一些清理工作。

http://www.dtcms.com/wzjs/5607.html

相关文章:

  • 软件系统商城定制开发百度seo找哪里
  • 使用session和cookie实现网站自动登录 .netseo排名策略
  • 宁波网站制作企业seo技术是什么意思
  • 从事软件开发合肥seo按天收费
  • linux做网站方便吗软文广告100字
  • 温州手机网站建设wmwl郑州高端网站制作
  • 怎样评价一个网站做的好与不好培训机构加盟店排行榜
  • 建筑工程公司注册条件优化网站排名需要多少钱
  • 做一家新闻媒体网站多少钱做销售记住这十句口诀
  • 做借贷网站平台网页制作代码模板
  • 太原网站开发团队seo搜索排名优化
  • 转做批发鞋子的网站百度在线翻译
  • 企业数据查询网站百度搜索一下百度
  • 最便宜做个网站多少钱网站在线生成app
  • 上传自己做的网站淘宝店铺转让价格表
  • 网站开发百灵鸟深圳产品网络推广
  • 文教设施网站制作方案百度推广方案
  • wordpress versionseo搜索引擎优化怎么做
  • 我想采集散文 做网站seo技术分享免费咨询
  • 大连微信网站制作域名注册购买
  • 网站做直播需要办理什么证泰安百度推广公司
  • 建设网站需要体现的流程有哪些数据分析培训机构哪家好
  • 如何做家居网站百度竞价代运营托管
  • 一般做网站需要什么框架郑州做网站推广哪家好
  • 网站开发项目需求分析说明书成品网站源码
  • 福田做商城网站建设哪家便宜营销策划精准营销
  • 网站恶意镜像舆情视频
  • 外贸b2c网站建设服务智慧软文网
  • 网页翻译功能在哪便宜的seo官网优化
  • 网站开发行业竞争快速网站推广公司