GC在Java中的核心功能就是对内存中的对象的分配与回收,所以对于GC的理解不要局限于只是进行垃圾收集,还应该知道GC决定了内存的分配
最常见的的情况时当创建一个对象后,GC就会监视这个对象的地址,大小和状态。对象的引用会保存在栈内存(Stack)中,而对象的具体内容会保存在堆内存(Heap)中。当GC监测到一个堆中的某个对象不再被栈所引用时,就会不定期的对这个堆内存中保存的对象进行回收。有了GC的帮助,开发者不用再考虑内存回收的事情,GC也可以最大限度地帮助开发者防止内存泄漏。
在Java中针对垃圾收集也提供了多种不同的处理分类。
(1)引用计数:一个实例化对象,如果程序使用了这个引用对象,引用计数加1,当一个对象使用完毕,引用计数减1,当引用计数为0时,则可以回收。
(2)跟踪收集:从root set(包括当前正在执行的线程,全局或者静态变量,JVM)开始扫描有引用的对象,如果某个对象不可到达,则说明这个对象已经死亡,则GC可以对其进行回收。也就是说:如果A对象引用了B对象的内存,那么虚拟机会记住这个引用路径,而如果一个对象没有在路径图中,则就会被回收。
(3)基于对象跟踪的分代增量收集:所有的对象回收要根据堆内存的结构划分来进行收集,具体如下:
①基于对象跟踪:是由跟踪收集发展而来,分代是指对堆进行了合理的划分,JVM将整个堆分为三代:
A:YougGen(新生代,使用Minor GC回收):YougGen区里面的对象的生命周期比较短,GC对这些对象进行回收的时候采用复制拷贝算法。
I- youg:又分为eden,survivorl(from space),survivor2(to space)。eden是在每个对象创建的时候才分配的空间,当eden无法分配时,则会自动触发一次Minor GC。当GC每次执行时都会将eden空间中存活的对象和survivorl中的对象拷贝到survivor2中,此时eden和survivor1的空间内容将被清空。当GC执行下次回收时将eden和survivor2中的对象拷贝到surivorl中,同时会清空eden和survivor2空间。按照此类的顺序依次执行,经过数次回收将依然存活的对象复制到OldGen(年老代)区。
B:OldGen(年老代,使用Major GC回收):当对象从YoungGen保存到OldGEn后,会监测OldGen的剩余空间十分大于要晋升对象的大小,此时会有以下两种处理方式。
I- 如果小于要保存的对象,则直接进行一次 Full GC(对整个堆进行扫描个回收,但是Major GC除外),这样就可以让OldGen腾出更多的空间。然后执行Minor GC,把YoungGen空间的对象复制到OldGen空间。
I- 如果大于要保存的对象,则会根据条件(HandlePromotionFailure配置:是否能担保分配失败内存,即整个OldGen空间不足,而YoungGen空间中Eden和Survivor对象都存活的极端情况。)进行Minor GC和Full GC回收。
C,PermGen(持久区):要存放加载进来的类信息,包括方法,属性,对象池等,满了之后可能引起Out Of Memory错误。
MetaSpace(元空间):持久化的替换者,直接适用主机内存进行存储。
增量收集:不是每一次全波手机,而是累计的增量收集。
在下篇我会用图解的方式来解释这一大篇文章,结合图像更好的对GC的理解~~~~
深入分析GC处理
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 《深入理解Java虚拟机》笔记_第一遍 先取看完这本书(JVM)后必须掌握的部分。 第一部分 走近 Java 从传...
- 通过这篇文章你能知道的问题: 1.如何判断对象是活着还是死去? 2.在Java语言中,可作为GCRoots的对象有...