做者:正号先生˚
html
https://www.cnblogs.com/zhxiansheng/p/11294529.htmljava
1|0新生代和老年代
对象在被实例化以后,都是属于新生代。算法
大部分新生代的生命周期都是及其短暂的,例如在一个方法中建立的对象会随着方法执行完毕,栈空间的栈帧出栈后而失去引用。安全
而有一些对象确实会长期存活在堆内存的,好比被Static引用的对象。这种对象不会轻易的被垃圾回收器回收。微信
因此JVM会将堆内存分为两个区域,一个年轻代,一个老年代。jvm
其中年轻代,顾名思义,就是建立和使用完以后立马就要被回收的对象放在里面。而后老年带呢,就是把一些会长期存活的对象放在里面。jsp
1|1为何要分红新生代和老年代
不少人都会有一个疑问,为何要划分两个区域呢?ide
由于这个垃圾回收有关,对于年轻代的对象,他们的特色是很快就会被回收,因此须要使用一种垃圾回收算法。优化
而对于老年代而言,里面的大部分对象可能都会长期存活,那么使用新生代的回收算法放在这里就可能并非那么的合适。须要有着本身的一套回收算法。this
2|0什么是永久代
很简单,JVM里的永久代其实就是咱们以前说的方法区
所谓的永久代,你能够认为是存放一些类的信息,在上一个章节咱们知道咱们生成的.class就是存放在这个区域的。通常状况下,咱们对于jvm调优都是对新生代和老年代进行调优。通常而言永久代保持默认配置就能够了。
是否是意味着咱们就不须要关注永久代?
确定不是的。由于要存储类的相关信息,因此对于动态生成类的状况比较容易出现永久代的内存溢出。最典型的场景就是,在 jsp 页面比较多的状况,容易出现永久代内存溢出。
3|0如何判断一个对象是不是垃圾
咱们知道,当一个对象被建立出来的时候,好比说在一个方法中建立一个对象,当该方法执行完毕后,就没有引用指向这个对象了,这个对象就会变成垃圾对象。
这仅仅是一种状况。
到低哪些对象是辣鸡,哪些对象不是?
JVM中使用了一种可达性分析算法来断定哪些对象是能够被回收的。这个算法的核心就是看这个对象有谁在引用它,而后一层一层的往上判断,看是否被GC roots所引用。
在java中,可做为GC Roots的对象有:
1.虚拟机栈(栈帧中的本地变量表)中引用的对象(也就是咱们前面提到在方法中建立的对象);2.方法区中的类静态属性引用的对象;3.方法区中常量引用的对象;4.本地方法栈中JNI(即通常说的Native方法)中引用的对象
当一个对象没有被上述所引用,那么这个对象就能够被认为是垃圾对象了。
总之记住一句话,只要你的对象被方法的具有变量,类的静态变量给引用了,就不会回收他。
3|1java中对象不一样的引用关系。
一、强引用
就是被GC roots所直接引用的对象。只要是强引用关系,那么垃圾回收器是绝对不会回收这个对象的。
二、软引用
public class test{public static SoftReference<ReplicaManager> manager =new SoftReference<ReplicaManager>(new Replicamanager)}
/**如上诉代码,实例对象被“SoftReference” 软引用类型的对象包装起来了,那么这个对象的引用就是软引用。
正常状况下是不会回收软引用对象的,可是若是你进行垃圾回收后,返现内存仍是不够存放新的对象的时候,这个时候就会吧软引用的对象给回收掉**/
三、弱引用
这个相对前两中使用的不多,与软引用类时,当一个实例对象被“WeakReference”弱引用的对象包装起来的时候,那么这个对象就是弱引用。弱引用的生命周期就存在下一次垃圾回收以前,也就是说下一次垃圾回收会回收掉弱引用的对象。
四、虚引用
最弱鸡的一种引用,我感受没什么做用。一个对象是否是虚引用对他本生的生命周期没有影响。该何时回收就何时回收。设置他惟一的目的就是被回收的时候会获得一个系统通知,通常来讲没什么卵用
3|2finalize()方法的做用
到这里,我相信你应该清楚了哪些对象会被回收哪些对象不会被回收。
若是一个对象被GC Roots所引用,可是!!他若是是软引用或弱引用,那么也是可能会被辣鸡回收器给回收掉的。
在垃圾对象被回收的时候,会调用Object对象的finalize()方法。
咱们来模拟一个辣鸡的自我救赎代码。
public class A{public static A instance;@Overrideprotected void finalize() throws Throwable{ A.instance = this; }}
当对象被回收的时候,调用finalize方法,从新将GC Roots的变量引用指向本身,那么就不会被回收了。
这个基本上没人用,感受就是一个sb才会写的代码。写出来就是给你们说出这个细节。
4|0新生代对象是如何变成老年代对象的
4|1长期存活的对象会屡次躲过垃圾回收
躲过多少次Minor GC而没有被回收掉,咱们就认为这个对象的年龄有几岁了,默认状况下,当一个对象10多岁的时候,就认为他是一个老人了。须要被转移到老年代去。
想一想也正常,新生代的竞争压力这么大,老年对象仍是早点去老年代比较好不与年轻人竞争资源。
4|2特别大的超大对象直接不通过新生代就进入老年代
年轻代的的竞争原本就很大,你还要占用那么多资源,不行不行,你仍是去老年代吧。
4|3动态年龄判断机制
这一部分须要结合垃圾回收器的算法来说,就是复制算法。咱们在后面的章节会讲到,这里大概介绍一下。
咱们通常会将新生代分为三个区域,一个Eden,两个Survivor。比例8:1:1.
生成的对象默认在eden区域。当发生一次Minor GC后,会将存活的对象复制到其中一个Survivor区域。当下一次GC后又会将存活的对象复制到另外一块Survivor。这么作的好处是减小内存碎片。
当咱们发生一次GC后,将存活对象放到其中一块survivor区域。发现其中的1岁,2岁,3岁的对象年龄加起来内存超过survivor区域的一半,就会把4岁以及4岁以上的对想转移到老年代。
4|4GC后survivor区域存放不下
这个没办法,GC后都还存放不下通常来讲要不是访问量激增,要么就是优化的不到位,因此只好将这写对象转移到老年代。
4|5空间担保机制
在发生minor gc以前,虚拟机会检测 : 老年代最大可用的连续空间>新生代all对象总空间?
一、知足,minor gc是安全的,能够进行minor gc。
二、不知足,虚拟机查看HandlePromotionFailure参数:
(1)为true,容许担保失败,会继续检测老年代最大可用的连续空间>历次晋升到老年代对象的平均大小。若大于,将尝试进行一次minor gc,若失败,则从新进行一次full gc。
(2)为false,则不容许冒险,要进行full gc(对老年代进行gc)。
本文分享自微信公众号 - java1234(gh_27ed55ecb177)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。