首页 > 代码库 > JAVA内存模型及垃圾回收自我总结

JAVA内存模型及垃圾回收自我总结

本文为原创,根据《深入理解java虚拟机》和自己的一些理解进行整理,单纯和看其他人的博客感觉不如自己一点点的画和记录来的印象深刻

JAVA内存模型:

技术分享

判断对象是否已死(可以回收)的算法

技术分享

方法区(永久代)回收的相关说明:

永久代的垃圾回收主要两部分内容:废弃的常量和无用的类。废弃的常量:无任何对象引用此常量。无用的类:1、该类所有实例已经被回收(堆中不存在该类的任何实例)。2、加载该类的ClassLoader已经被回收。3、给类对应的Class对象没有任何地方呗引用,无法在任何地方通过反射访问该类的方法

垃圾收集的算法:

1、标记 - 清除算法

包含标记和清除2个阶段,是最基础的算法。标记就是标记出那些已经可以被回收的对象,在标记完成后进行清楚,此算法效率不高而且会产生内存碎片,当程序在以后的运行中需要分配一块大的连续的内存时可能因为内存碎片的问题而提前触发再次垃圾回收。

过程示意图如下:

技术分享

2、复制算法(新生代采用的算法之一)

为了解决标记-清除 算法 的效率问题的,将内存划为多块,在标记完一块区域的对象的存活状态后,将存活的对象拷贝到另外一块上,然后将之前的那块一次清理掉。

在新生代上对象存活期很短,并且98%的对象是朝生夕死,所以在内存的划块上不需要1:1进行划分,hotspot虚拟机默认按照Eden-80%,两块Survivor各10%进行划分(8:1),其中Eden和一块Survivor空间用来存放新生代的对象,还有一块用来复制垃圾回收时Eden和另外一块Survivor的存活对象,然后一次清除调用Eden和那块Survivor内存,下次垃圾回收时这2块Survivor的功能互相调换。当一块Survivor不够装下存活的对象时,则会向老年代的分配担保机制(借内存)进入到老年代。

正常对象从新生代进入老年代的逻辑:

当一个新生代的对象经过一轮一次垃圾回收后未被回收,则此对象一个标识符会自增+1,当对象的标识达到某个阀值则会放置到老年代去。

复制算法的示意图:

技术分享

 

3、标记 - 整理算法

相比标记-清理算法,此算法解决了标记-清理算法的内存碎片问题,清理完可回收的对象后会对该内存块进行整理。

算法示意图:

技术分享

4、分代收集算法

 当前商业虚拟机都采用此算法,其实说这是算法还不如说是一个将前面3个算法在新生代和老年代上应用不同算法的一个策略,新生代采用复制算法,老年代采用“标记-清除”或者“标记-整理”算法。

垃圾回收器(垃圾收集算法的具体实现)

HotSpot 1.6版Update22的收集器入下所示:

技术分享

上面部分是新生代的垃圾回收器,下面部分是老年代的垃圾回收器,中间的连线表示这2个回收器可以配合一起使用。

 

1

JAVA内存模型及垃圾回收自我总结