JAVA垃圾回收与GC浅谈
来源:互联网 发布:java jvm原理 一句话 编辑:程序博客网 时间:2024/06/05 19:35
众所周知,java中的对象能够在"无用"的时候被GC回收,腾出空间,但是具体什么样的对象在什么样的情况下被怎样回收,其实过程还是有些小复杂,接下来就简要的谈谈这些过程:
问题一:何为"无用"对象。
1. 无任何引用的对象;根据该思想,诞生一种“引用计数法”来判断对象的存活性--
思路:给对象添加一个引用计数器,当引用计数器为0的时候,代表对象可回收;
缺点:无法解决循环引用,整个对象无用问题;
因此,该思想与方法虽然也有一些虚拟机在用,但是比较少见。
2.为了克服“引用计数法”所带来的缺陷,提出了“根搜索算法(GC Root)”;
思路:若一个对象,或者一些列对象到GC Root没有引用链接,则算作可回收已死对象;
GC Root:总的来说,就是一个对象的初始引用,不包括其他内部的二次引用;具体有如下几种情况--
a.虚拟机栈(栈帧中本地变量表中)的引用;
b.本地方法栈中JNI的引用;
c.方法区中常量的引用;
d.方法区中静态变量的引用;
特别注意:不包括堆中对象的所持有的实例变量;
例如:
class A{public B b = null;}class B{}public void case1(){B b1 = new B();A a1 = new A();//A中的实例变量b指向了对象ba1.b = b1;}在上面的例子中,a1,b1都是方法case1()中的本地变量,因此都存在与java虚拟机栈栈帧中的本地变量表中,此刻,对象b1和a1的都有到GC ROOT的引用链,其中a1的GC ROOT是变量a1,b1的GC ROOT是变量b1和a1;这时,如果令b1=null;这时,对象b1将失去b1这个变量,即GC ROOT,但是,该对象还是有一个引用在身,即a1.b = b1;而a1本身又是有GC ROOT的存货对象,因此b1的引用链任然可以延伸至a1变量,即b1对象任然有GC ROOT; 但如果此刻令 a1 = null;则虽然b1对象还是有引用在身,即a1.b=b1,但是该引用只是堆中的实例变量的引用,不可作为GC ROOT,因此,此刻b1找不到任何GC ROOT引用链了,即b1为“无用对象”,当然此刻a1也为无用对象。
优点:解决了循环引用不可回收问题;因此也被作为目前最为广泛应用的判断对象存货的方法。
补充:“无用类”;
方法区中的类信息同样也会被GC回收处理,一个类无用,需要满足以下3个条件:
A.该类所有实例(对象)均已经回收;
B.加载该类的ClassLoader已经回收;
C.该类对应Class对象没有被引用;
问题二:怎样回收对象。
当虚拟机知道了哪些对象该被回收后,就该采取一定措施实施回收了,主要有-标记清除法,复制回收法(Eden,survivor),
标记-整理算法,分代收集算法;
1.标记清除法;如图1,是运用该方法回收对象的依次完整GC过程;
图1
2.复制回收法;
该方法在分配内存的时候,就将内存进行划分,分成8:1:1的比例,其中最大的一块为Eden,两块较小的为Survivor;
在分配的时候,都是用Eden和一块Survivor,进行GC后仍然存活的对象,移动到另一块Survivor,然后把第一块Survivor和Eden
里的对象都清空;这里,新分配的对象都是在Eden区域,但是GC覆盖面是Eden和一块Survivor,被判定为存活的对象,通通复制到另一块
Survivor,然后清空其余两块区域内的对象;这时,两块survivor的角色互换了,空的一块作为下一轮GC接收复制存活的对象。
特点:由于短期的活动内存区较大,而长期的内存保存区域较小,所以适合新生代,活动频繁的算法。
3.标记-整理算法
与标记清理法过程差不多,标记过程一致,但是最后清理对象的时候,不是直接清理,而是把未标记的对象往一侧移动,然后清
理掉末端的其他所有标记的对象;
特点:当存活对象较为多的时候,则移动间隔不是很多,因此采用该方法对于老年代比较适合。
4.分代收集算法
综合上诉各种方法特点,将java堆分为新生代和老年代,新生代-对象朝生晚死,生命周期短的区域;老年代-对象一般存活较久
生命周期较大;
对于新生代采用复制回收法,老年代采用标记-清理或者标记整理法。
问题三:对象如何分配。
对象分配大致原则如下图2:
1. 优先分配新生代->Eden->不够分->minGC,复制回收法转Survivor->无法回收->转老年代->新对象分配于Eden
(MinorGC-新生代GC;MajorGC/FullGC老年代GC)
2. 大对象直接分配老年代,避免复制回收法大量频繁复制;
3. 新生代中(Survivor存活区)年龄超过阀值,进入老年代(一次MinorGC后长一岁,第一次GC为一岁)
4. 新生代中Survivor中的相同年龄的对象大小和超过Survivor的一半,则该年龄对象进入老年代;
- JAVA垃圾回收与GC浅谈
- 浅谈gc-垃圾回收
- 浅谈GC垃圾回收器
- java垃圾回收与System.gc()介绍
- java垃圾回收与System.gc()介绍
- java垃圾回收与System.gc()介绍
- java垃圾回收GC
- Java 垃圾回收 GC
- JAVA垃圾回收GC
- java 垃圾回收GC
- java GC 垃圾回收
- Java 垃圾回收GC
- T626code学习笔记之浅谈Java垃圾回收(GC)
- [Java GC]Java垃圾回收
- 浅谈Java垃圾回收
- 浅谈Java垃圾回收
- 浅谈Java垃圾回收
- Java垃圾回收浅谈
- android annotation快速简单入门
- phpstorm9安装
- hdu 2063
- 快速傅里叶变换算法探幽
- UI--手势方法介绍
- JAVA垃圾回收与GC浅谈
- C++构造函数初始化列表 委托构造函数
- ios工作笔记
- 软件性能测试的几种方法
- LibSVM(java版)的使用
- 阿里云服务器配置php+apache+mysql+phpMyadmin开发环境并上传本地代码
- 光流检测运动物体
- 【生活感触】:生活要稳健(只看标题即可)
- UIImage_Category