【大白话系列】深入浅出Cleaner+虚引用完成堆外内存的回收
在NIO技术中,使用allocateDirect()方法可以创建直接内存;如何释放该内存呢?
(1)通过手动释放内存(Cleaner+虚引用)
(2)交给JVM进行处理(Full GC)
文章目录
- 1.直接内存的创建与销毁
- 2.通过Cleaner+虚引用完成堆外内存回收
- 3.总结创建与销毁流程
- 4.如何一步步顺序解读源码流程
- 5.使用直接内存的利弊分析
1.直接内存的创建与销毁
base = UNSAFE.allocateMemory(size);
在DirectByteBuffer类构造方法中,主要通过allocateMemory方法完成堆外内存的创建,这个方法是Unsafe类中,这个类是干什么的呢?通过名字我们可以也可以看出这个类是不安全的,也就是它是能够直接操作堆外内存,超出了JVM的管辖范围!
UNSAFE.freeMemory(address);
需要注意的是通过Unsafe开辟的直接内存,需要通过调用freeMemory手动回收(当然帮你写了)
2.通过Cleaner+虚引用完成堆外内存回收
Java对象有四种引用方式:强软弱虚
虚引用PhantomReference一般来说极少使用,而且它不能单独使用,它需要和引用队列 ReferenceQueue一块使用
首先分析allocateDirect()方法底层(DirectByteBuffer类)
通过它的构造方法可以看出创建了Cleaner对象和Deallocator对象,首先分析Cleaner对象,通过看它的源码可以得出,它的底层维护了一个双向链表,当Cleaner对象初始化时,就会加入到这个Cleaner双向链表中(而且是安全的,使用了Synchronized,Cleaner类继承了虚引用)
public static Cleaner create(Object ob, Runnable thunk) {if (thunk == null)return null;return add(new Cleaner(ob, thunk));}
当DirectByteBuffer对象不存在时,Cleaner对象不再处于引用链中,等到下一次GC时,Cleaner会被加入到ReferenceQueue队列中,并执行clean方法;将将自身从Cleaner双向链表中移除(remove),然利用多态调用了Deallocator类中的run方法释放内存
public void clean() {if (!remove(this))return;try {thunk.run();} catch (final Throwable x) {AccessController.doPrivileged(new PrivilegedAction<>() {public Void run() {if (System.err != null)new Error("Cleaner terminated abnormally", x).printStackTrace();System.exit(1);return null;}});}}
public void run() {if (address == 0) {// Paranoiareturn;}UNSAFE.freeMemory(address);address = 0;Bits.unreserveMemory(size, capacity);}
3.总结创建与销毁流程
分析下图总结流程(来源百度图片)
初始时,创建了一个DirectByteBuffer对象,在DirectByteBuffer的构造函数中创建了一个Cleaner对象和Deallocator对象;Cleaner对象初始化时将自身加入到了链表中;一旦DirectByteBuffer对象被回收,那么下次GC时Cleaner(继承了虚引用)对象会被放到ReferenceQueue队列中并执行clean方法(多态调用了Deallocator中的run方法释放内存)
4.如何一步步顺序解读源码流程
(1)ByteBuffer抽象类的allocateDirect方法
(2)DirectByteBfufer的构造方法
(3)Cleaner类的create方法
(4)Cleaner类的add方法
(5)回到第二步
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
(6)Deallocator类的构造方法
将Cleaner类中分配的直接内存的地址、大小等进行复制,因为这个类的run方法是进行内存回收的根方法。
5.使用直接内存的利弊分析
使用直接内存肯定也有坏处,否者还有堆内存什么事;使用直接内存不受JVM的管辖,稍有不慎容易造成内存泄漏!当然使用直接内存减少了GC的时间(交给了操作系统进行管理),另一方面与磁盘交互时使用直接内存减少了复制操作,效率得到提高。
【大白话系列】深入浅出Cleaner+虚引用完成堆外内存的回收相关推荐
- Java 四种引用类型:强引用、软引用、弱引用、虚引用
以前学习强软弱虚引用的时候,只是走马观花看看博客,并没有自己写代码去实践.去证明,导致每次看完后,过不了多久就忘了,后来下定决心,一定要自己敲敲代码,这样才能让印象更加深刻,古人云:纸上得来终觉浅,绝 ...
- 强软弱虚引用,只有体会过了,才能记住
以前学习强软弱虚引用的时候,只是走马观花看看博客,并没有自己写代码去实践.去证明,导致每次看完后,过不了多久就忘了,后来下定决心,一定要自己敲敲代码,这样才能让印象更加深刻,古人云:纸上得来终觉浅,绝 ...
- 阿里面试: 说说强引用、软引用、弱引用、虚引用吧
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 我们都知道 JVM 垃圾回收中,GC判断堆中的对象实例或数 ...
- java-基础-强、软、弱、虚引用
Java的四种引用,强弱软虚,用到的场景. JDK1.2之前只有强引用,其他几种引用都是在JDK1.2之后引入的. 强引用(Strong Reference) 最常用的引用类型,如Object obj ...
- 回过头来看对象的四种状态强软弱虚引用的理解
一.对象的四种引用状态描述 在JDK1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference).软引用(Soft Reference).弱引用(Weak Refe ...
- java 对象引用 弱引用吗_Java对象的强引用、软引用、弱引用和虚引用 笔记
从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 1.强引用 使用最普遍的引用.如果一个对象具有强 ...
- 那些令人发燥的JAVA虚引用
在Java的世界里,对象的存在层次,也有三六九等,充满了阶层之间的嘲弄.强软弱虚各种引用,对于熟悉Java的同学一定不会感到陌生,它们随着等级的降低,越来越没存在感.平常使用的对象,大多数就是强引用的 ...
- java基础-----弱引用,软引用,强引用,虚引用
转自:http://www.cnblogs.com/blogoflee/archive/2012/03/22/2411124.html 1.概述 在JDK1.2以前的版本中,当一个对象不被任何变量引用 ...
- 强引用 弱引用 软引用 虚引用 的区别以及使用场景
一·. 强引用(Strong Reference) 我们使用的大部分的引用都是强引用,这是使用最普遍的引用.如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它.当内存空间不足 ...
最新文章
- 小米做的这件事,捍卫了你的隐私
- 虚拟桌面最佳组合---Windows 7
- 脚本:获取CSDN文章的访问量
- 在Editplus中搭建Ruby开发环境
- Android之提示Could not find com.android.support:appcompat-v7:25.3.1.
- cf1556B B. Take Your Places!
- Linux的SOCKET编程 简单演示
- oracl 单行字符型函数
- STM32之SysTick例程
- 假如给Go语言加上注解,程序会变怎样?
- Linux之父和Redis之父,Redis之父:10x程序员应该具备哪些素质
- Javascript加号的作用、数据类型、输入用户的输入第四课
- Java加密的几种方式
- 计算机cad知识,计算机与Cad制图知识点.doc
- Linux嵌入式系统的电子相册代码,基于嵌入式Linux和Qt编程实现数码相框的设计
- H3C新华三笔记本FN键锁定
- kali linux 怎么攻击IP,Kali Linux实战篇:Ettercap 使用教程 DNS欺骗攻击实战
- 7.交易开拓者-公式进阶(一)
- 商城-商品规格管理-商品规格参数管理
- 国家与地区缩写 + 各国语言缩写
热门文章
- 学习总结初篇:发现问题
- controller需要捕获异常吗_Spring之Controller异常处理
- java类加载器_类加载器
- java成果_JAVA WEB期末项目第二阶段成果
- 数组排序思想———选择排序
- CSS基本选择器、层次选择器、结构伪类选择器、属性选择器
- mysql 重启失败,重启MySQL服务失败
- python输入水果求个数问题_水果爱好者:用Python解决一个简单的分类问题
- 软工专硕考研_分析|华北电力(北京)大学20计算机考研报录分析!电子信息复试狂刷114人,软工专硕复试录取高达1:4.7!...
- 二、 elasticsearch安装和概念