java垃圾回收机制:
1、内存泄漏和内存溢出的区别:
内存溢出:本质是指内存不足,
内存泄漏:是指内存充足,但使用之后,并没有及时的去释放资源。
2、gc线程关闭的方式
(1)、进程关闭
(2)、system.exit()
(3)、程序中断
(4)、程序代码执行完毕
注意:gc线程关闭后,并不会立即消失
3、垃圾回收机制算法
(1)、引用计数法
给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1,当计数器次数过多时,就把这个对象放到老年代中,如果每次不被引用的时候,计数器的次数就减1,一直减到0,被标不可用了,说明这个对象可以被回收了,然后垃圾收集器将回收该对象使用的内存。
优点:
引用计数收集器可以很快的执行,交织在程序运行中。对程序需要不被长时间打断的实时环境比较有利。
缺点:
无法检测出循环引用。如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0.而且每次加减非常浪费内存。
(2)、标记清除法
标记-清除(Mark-Sweep)算法顾名思义,主要就是两个动作,一个是标记,另一个就是清除。
标记就是根据特定的算法(如:引用计数算法,可达性分析算法等)标出内存中哪些对象可以回收,哪些对象还要继续使用,在标记完成后统一回收掉所有被标记的对象 ,标记指示对象还要继续使用的,那就原地不动留下
缺点:
- 标记与清除效率低;
- 清除之后内存会产生大量碎片;
(3)、复制算法
S0和s1将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。这样使得每次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况实现简单,运行高效。
复制算法用于在新生代垃圾回收
它的主要缺点有两个:
(1)效率问题:在对象存活率较高时,复制操作次数多,效率降低;
(2)空间问题:內存缩小了一半;需要額外空间做分配担保(老年代)
(4)、标记压缩算法
标记压缩法在标记清除基础之上做了优化,把存活的对象压缩到内存一端,而后进行垃圾清理,通过这种方式来进行减少碎片的目的。
(java中老年代使用的就是标记压缩法)
(5)、分代算法
“分代收集”算法,把Java堆分为新生代和老年代,然后 对新生代和老年代进行垃圾回收。
这样就可以根据各个年代的特点采用最适当的收集算法
gc线程进行垃圾回收的时候,其他线程会处于等待状态。
等待的原因是为了防止,在gc线程进行垃圾回收的时候,其他线程继续创建新的对象