JVM垃圾回收

如何判断对象可以回收

用两种算法判断:引用计数法,可达性分析算法

引用计数法

引用计数法:对象实时被引用的次数,引用次数为0,代表可被回收。

循环引用可能出现问题。各自引用计数都是1。导致AB对象都不会被删

JVM垃圾回收_第1张图片

可达性分析算法

Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象

根对象指肯定不能被当成垃圾的对象

算法原理:先扫描堆中所有对象,看看对象是不是被根对象直接或间接的引用,如果是那就不能被回收,vice versa。
扫描堆中的对象,看是否能够沿着 GC Root对象 为起点的引用链找到该对象,找不到,表示可以
回收

哪些对象可以作为 GC Root ?(根对象)

利用Memory Analyzer工具,jmap(查看堆内存占用情况,抓取内存快照,再用Memory Analyzer分析快照)

命令:jamp -dump:format=b,live,file=filename.bin 进程ID(利用jps查看)

转储文件格式       抓快照时只抓存活的,还会触发一次垃圾回收               文件存储的位置

Memory Analyzer打开刚才生成的文件,javabasics--GCroots就可以查看

四种引用

1. 强引。用被GC Roots 对象的引用就是强引用

只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收

只要被强引用,该对象就不会被回收

2. 软引用(SoftReference)

仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次出发垃圾回收,回收软引用
对象。可以配合引用队列来释放软引用自身

垃圾回收后,内存还不够,那就回收被软引用的对象

3. 弱引用(WeakReference)

仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象
可以配合引用队列来释放弱引用自身

4. 虚引用(PhantomReference)

必须配合引用队列使用,主要配合 ByteBuffer 使用,被引用对象回收时,会将虚引用入队,
由 Reference Handler 线程调用虚引用相关方法释放直接内存

5. 终结器引用(FinalReference)

无需手动编码,但其内部配合引用队列使用,在垃圾回收时,终结器引用入队(被引用对象
暂时没有被回收),再由 Finalizer 线程通过终结器引用找到被引用对象并调用它的 finalize
方法,第二次 GC 时才能回收被引用对象

引用队列

被软/弱引用的对象被回收后,软/弱引用本身也是一个对象(也占用内存),如果开始有引用队列,那就会被放到引用队列里。利用引用队列找到软/弱引用本身,然后释放

垃圾回收算法

分代垃圾回收

垃圾回收器

垃圾回收调优

你可能感兴趣的:(java,jvm,算法)