1.怎么判断文件是否需要收集?
1.引用计数算法
给对象添加一个引用计数器,每当对象被引用一次就加1,引用失效时就减1。当为0的时候就判断对象不会再被引用。
缺点:难以解决循环引用的问题,就是假如两个对象互相引用已经不会再被其它其它引用,导致一直不会为0就无法进行回收。
2.可达性分析算法
这个算法有效解决了循环利用的弊端。
6%)(Q.png
它的基本思路是通过一个称为“GC Roots”的对象为起始点,搜索所经过的路径称为引用链,当一个对象到GC Roots没有任何引用跟它连接则证明对象是不可用的。
2.1哪些能当做GC roots?
①虚拟机栈中的引用的对象,就是平时所指的java对象,存放在堆中。
②方法区中的类静态属性引用的对象
③方法区中的常量引用的对象,
④本地方法栈中native方法引用的对象
⑤所有被同步锁(synchronized关键字)持有的对象
2.2被标记了一定会被回收吗?
不一定,如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记,随后进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。假如对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,那么虚拟机将这两种情况都视为“没有必要执行”。
2.什么时候会发生GC?
Minor GC :eden区内存不足造成
Full GC:
1.老年代满了
2.System.gc();
3.MinorGC发生后,前面平均移到老年代的容量大于现在老年代还剩下的空间
4.大对象直接到老年代,但是老年代没有足够大的连续空间
3.垃圾收集有什么方法?
标记-清除(会造成内存泄漏)
复制 (需要一半的内存来作为复制区,新生代算法)
标记整理
分代收集理论:绝大多数对象都是朝生夕灭的。
(就是把上面几个算法在不同的代,不同的收集器上使用)
为什么需要不同的算法?
对于年轻代的对象,由于对象来的快去得快,垃圾收集会比较频繁,因此执行时间一定要短,效率要高,因此要采用执行时间短,执行时间的长短只取决于对象个数的垃圾回收算法。但是这类回收器往往会比较浪费内存,比如Copying GC,会浪费一半的内存,以空间换取了时间。
对于老年代的对象,由于本身对象的个数不多,垃圾收集的次数不多,因此可以采用对内存使用比较高效的算法。
4.有哪些垃圾收集器?
虽然垃圾收集器的技术在不断进步,但直到现在还没有最好的收集器出现,更加不存在“万能”的收集器,所以我们选择的只是对具体应用最合适的收集器
Serial收集器:默认新生代收集器,与其他单线程的收集器相比,简单而高效,消耗内存小,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率,因为新生代的大小通常比较小,虽然会有stop the world,但是可控制在十几、最多一百毫秒,完全可以接受。
Parallel Scavenge收集器:新生代的并行收集器,不关注停顿时间,而是代码吞吐量。
Serial Old:Serial老年代版本,作为CMS失败后的替代品
CMS收集器(Concurrent Mark Sweep)是以一种获取最短回收停顿时间为目标的收集器。(并发收集)【重视响应,可以带来好的用户体验,被sun称为并发低停顿收集器】
一开始先标记GC Roots能直接标记到的对象(会停顿)
然后开始延伸(不会停顿)
再之后修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(会停顿)
最后就是清理啦,因为不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。(不会停顿)特点:
1.cpu敏感,根据cpu核数来决定垃圾线程的数量(cpu核数+3)/4
2.用标记清除算法,会造成内存泄漏,当然也有解决方案,直到内存空间的碎片化程度已经大到影响对象分配时,再采用标记-整理算法收集一次
3.无法处理浮动垃圾(就是线程在工作的时候垃圾线程也在工作,在这个时间段的垃圾是没办法清理的,需要等到下一次)
G1(garbage first,优先处理那些垃圾多的内存块的意思)收集器是当前最为前沿的收集器之一(1.7以后才开始有),同cms一样也是关注降低延迟,是用于替代cms功能更为强大的新型收集器,因为它解决了cms产生空间碎片等一系列缺陷。
标记与CMS类似,但是最后不同,先是标记GC Roots能直接关联到的对象(会停顿)
扫描整个堆里的对象图(并发标记,不停顿)
对用户线程进行暂停,处理并发标记的时候变动的对象(开始停顿)
筛选回收垃圾(根据设置的数值来控制回收的内存中垃圾大小)
对于区域的回收通过复制算法实现。在完成标记清理后,G1将这几个区域的存活对象复制到一个单独区域中,实现内存整理和空间释放g1的特别之处在于它强化了分区,弱化了分代的概念,它不属于新生代也不属于老年代收集器。
特点:
1.不会发生内存泄漏(用到了复制算法)
2.可以预测垃圾回收的时间(分块之后,时间少就先处理少一点,时间多就多处理点)
网友评论