垃圾回收机制算法分析
一、GC垃圾回收机制算法
1、引用计数法:
2、标记清除法:
3、标记压缩法:使用在老年代
4、复制算法:用在 新生代、s0、s1区
5、分代算法:分 新生代和老年代
垃圾回收机制、内存溢出与内存泄漏的区别?
什么是垃圾回收机制?
答:垃圾回收机制不定时的去 堆 内存清理不可达对象。
只要被引用了就是可达的对象。
想要垃圾回收机制去清理垃圾,就吧初始内存设置小一点。
让垃圾回收机制运行案例
package com.leeue.demo;
/**
*
* @classDesc: 功能描述:(测试执行垃圾回收机制)
* @author:<a href="[email protected]">李月</a>
* @Version:v1.0
* @createTime:2018年8月1日 上午10:38:27
*/
public class TestDemo01 {
public static void main(String[] args) {
//初始化堆内存设置小 垃圾回收机制就会执行概率变大
TestDemo01 testDemo01 = new TestDemo01();
//设置成null也能让垃圾回收机制执行概率变大。
testDemo01 = null;
System.gc();
}
/**
* 垃圾回收器执行之前执行。
*/
@Override
protected void finalize() throws Throwable {
//垃圾回收器调用之前调用这个函数
System.out.println("垃圾回收器执行了....");
}
}
二、内存溢出与内存泄漏的区别
内存溢出: 比如一个项目需要4g内存,现在机器只支持3G内存,这个就是内存溢出。
内存泄漏:对象已经别应用程序使用,但是垃圾回收器没有办法移除它,因为还在
被引用着。比如定义了许多static静态变量。静态变量垃圾回收机制不会去回收。
在永久区里。
垃圾回收机制都是在堆内存。
三、引用计数法
引用计数法:当一个对象标记为0的时候,gc直接回收掉,
当一个对象不被引用的时候,标记就-1,
如果这个对象又被引用了,标记就会+1。
每个对象有15次机会。
引用计数法面试回答:
每个对象都会有一个标记,默认是15次,gc回收时,对象不可达减去1,可达就+1
优点:引用计数法可以很快执行,在交织在程序运行。
缺点:无法检测出循环引用。如父对象有一个堆子对象的引用,
子对象反过来引用父对象,这样他们的引用计数永远不可能为0,
而且每次加减非常浪费内存。
四、复制算法
复制算法主要用在新生代里面:(edn s0与s1大小相等)
堆内存结构:
创建一个对象User, 进入edn区
当垃圾回收器发现User经常被引用的时候,就会将User对象放到S0区
再创建一个对象User2对象,进入edn区。
当垃圾回收器发现User2引用的时候,就会将User2对象放到s0区。
如果发现User不再被使用的时候,就会将User2对象移到到s1区,然后垃圾回收器
清楚整个S0区。
注意:s0区与s1区,只有一个区域是保存存活对象的,两个交替使用的。
总结:复制算法:优点:具有连续性,不会产生碎片化。因为清理都一整块区域。
碎片化:表示残留的。标记清除是一个个的清除,可能会产留。
五、标记清除算法
标记清除:为每个对象做一个标记,0表示可达,1表示不可达。
对象没有经常使用,将对象标记为1不可达。
注意不是连续的删除。
六、标记压缩算法
在标记清除算法上改进的,相等把标记清除算法的不可达对象放在了前面,排序了。
当GC清除的时候,直接清除前面所有的不可达对象。
标记清除和标记压缩算法用于老年代里面。
标记压缩算法:优点:没有碎片化。
标记清除算法和标记压缩算法用于老年代,因为一不用就清除掉对象。适用于老年代。
复制算法用于新生代。
七、分代算法
垃圾回收机制如果频繁使用会降低程序运行效率?
答:因为垃圾回收机制回收时其他线程都会停顿下,
原因是防止重新生成新的垃圾,这样就会清除不干净了
分代算法就是:根据不能的代,使用不同的算法
新生代:edn区使用计数法
s0与s1区使用:复制算法
老年代:使用标记压缩和标记清除
八、垃圾收集器与Jmeter压力测试工具的使用
什么是垃圾收集器?
答:垃圾收集器分为:串行收集器和并行收集器
串行收集器:单线程收集垃圾,效率低,回收期间暂停所有应用程序的执行。
并行收集器:在串行收集器基础上改进了,多线程收集垃圾,效率高