JVM进入老年代情况
1.躲过15次GC之后进入老年代
默认的设置下,当对象的年龄达到15岁的时候,也就是躲过15次Gc的时候,他就会转移到老年代中去
这个具体是多少岁进入老年代,可以通过JVM参数 “-XX:MaxTenuringThreshold”来设置,默认情况是15岁
2.动态对象年龄判断
假如说当前放对象的Survivor区域里一批对象的总大小大于了这块Survivor区域的内存大小的50%,那么此时大于等于这批对象年龄的对象,就可以直接进入老年代了
另外我们要理清楚一个概念,这个实际这个规则运行的时候是如下的逻辑:年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时就会把年龄n以上的对象都放入老年代
在没有回收的情况下 所有对象存活着
比如说一块s区块 100M 如果第一次有20M 不到老年代 第二次来了51M存活 如果之前的20M全部存活,那么这51M和20M将全部到老年代
另外一种情况 在这3次的对象都持续引用,不能回收的情况下,比如说一块s区块 100M 如果第一次有10M 不到老年代 第二次20M 第三次 31M 那么就会由于20+31>50了 那么第一次的10M就会到老年代了。
3.大对象直接进入老年代
有一个JvM参数,就是 -XX:PretenureSizeThreshold“,可以把他的值设置为字节数,比如“1048576”,就是1M
如果你创建一个大于这个大小的对象,比如一个超大的数组,或者是别的啥东西,此时就直接把这个大对象放在老年代中,压根不会经过新生代,这样可以避免新生代出现那种大对象,然后在2个Survivor区域里回来复制多次之后才能进入老年代
4.MinorGC后的对象太多无法放入Survivor区怎么办?
如果在Minor GC之后发现剩余的存活对象太多了,没办法放入另外一块Survivor,那么这个时候就必须得把这些对象直接转移到老年代中去
5.老年代空间分配担保规则
在执行任何一次Minor GC之前,JVM会检查一下老年代可用的可用内存空间,是否大于新生代所有对象的总大小
为啥会检查这个呢?因为最极端的情况下,可能新生代的Minor GC过后,所有对象都存活下来了,那岂不是新生代所有对象全部都要进入老年代?
如果说发现老年代的内存大小是大于新生代所有对象的,此时就可以放心大胆的对新生代发起一次Minor GC了,也可以转移到老年代去。
但是假如执行Minor GC之前,发现老年代的可用内存已经小于了新生代的全部对象大小了,那么这个时候是不是有可能在Minor GC之后新生代的对象全部存活下来,然后全部需要转移到老年代去,但是老年代空间又不够?
所以假如Minor Gc之前,发现老年代的可用内存已经小于看新生代的全部对象大小了,就会看一个-XX:-HandlePromotionFailure的参数是否设置了,如果有这个参数,那么就会继续进行下一步判断,
下一步判断,就是看老年代的内存大小,是否大于之前每一次Minor GC后进入老年代的对象的平均大小。
举个例子,之前每次Minor GC后,平均都有10MB左右的对象会进入老年代,那么此时老年代可用内存大于10MB
这就说明很可能这次Minor GC过后也是差不多10MB左右的对象会进入老年代,此时老年代空间是够的
如果上面那个步骤判断失败了,或者是 -XX:-HandlePromotionFailure“参数没设置,此时就会直接触发一次Full GC,就是对老年代进行垃圾回收,尽量腾出来一些内存空间,然后再执行Minor GC
如果上面2个步骤都判断成功了,那么就是说可以冒点风险尝试一下Minor GC 此时进行Minor GC,此时进行Minor GC有几种可能:
(1)Minor GC过后,剩余的存活对象的大小,是小于Survivor区的大小的,那么此时存活对象进入Survicor区域即可
(2)Minor GC过后,剩余的存活对象的大小是大于Survivor区域的大小,但是是小于老年代可用内存大小的,此时就直接进入老年代即可
(3)Minor GC过后,剩余的存活对象的大小,大于了Survivor区域的大小,也大于了老年代可用内存的大小,此时老年代都放不下这些存活对象了,就会发生Handle Promotion Failure的情况,这个时候就会触发一次Full GC
Full GC就是对老年代进行垃圾回收,同时也一般会对新生代进行垃圾回收。
因为这个时候必须把老年代理的没人引用的对象给回收掉,然后才可能让Minor GC过后剩余的存活对象进入老年代里面
如果要Full GC过后,老年代还是没有足够的空间存放Minor GC过后的剩余存活对象,那么此时就会导致所谓的OOM内存溢出了
JVM进入老年代情况的更多相关文章
- JVM 新生代老年代
1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...
- JVM新生代老年代详解
1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...
- jvm中的年轻代 老年代 持久代 gc
虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent Generation).其中持久代主要存放的是Java类的类信 ...
- JVM之堆内存(年经代,老年代)
一.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...
- JVM内存:年轻代、老年代、永久代(推荐 转)
参考文章: 1.Java 新生代.老年代.持久代.元空间 2.Java内存与垃圾回收调优 3.方法区的Class信息,又称为永久代,是否属于Java堆? Java 中的堆是 JVM 所管理的最大的一块 ...
- JVM的新生代、老年代、MinorGC、MajorGC
参考资料: http://blog.csdn.net/flamezyg/article/details/44673951 http://www.blogjava.net/ldwblog/archive ...
- JVM中的新生代、老年代和永生代
1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...
- JVM简介堆中新生代老年代浅析
一.JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成.1)程序计数器 几乎不占有内存.用于取下一条执行的指令.2)堆 所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx ...
- JVM堆内存相关的启动参数:年轻代、老年代和永久代的内存分配
如果想观察JVM进程占用的堆内存,可以通过命令工具jmap或者可视化工具jvisualvm.exe.JVM这些启动参数都拥有默认值,如果想了解JVM的内存分配策略,最好手动设置这些启动参数.再通过JD ...
随机推荐
- 挑战10个最难的Java面试题(附答案)【下】
查看挑战10个最难的Java面试题(附答案)[上] 在本文中,我们将从初学者和高级别进行提问, 这对新手和具有多年 Java 开发经验的高级开发人员同样有益. 关于Java序列化的10个面试问题 大多 ...
- 《手把手教你》系列进阶篇之1-python+ selenium自动化测试 - python基础扫盲(详细教程)
1. 简介 如果你从一开始就跟着宏哥看博客文章到这里,基础篇和练习篇的文章.如果你认真看过,并且手动去敲过每一篇的脚本代码,那边恭喜你,至少说你算真正会利用Python+Selenium编写自动化脚本 ...
- UIScrollViewDelegate相关方法
UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView;//scrollview 滚动的时候调用该方法, ...
- iOS开发-CoreMotion框架
转自: CoreMotion是一个专门处理Motion的框架,其中包含了两个部分 加速度计和陀螺仪,在iOS4之前加速度计是由 UIAccelerometer 类 来负责采集数据,现在一般都是用Cor ...
- Python脚本之三种运行方式,你会几个?
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:Jeremy_Lee123 一.交互模式下执行 Python 这种模式 ...
- 可扩展的Java线程池执行器
分享一下最近优锐课学习笔记. Java线程池执行程序偏向于排队而不是产生新线程.从好的方面来说,我们有两种解决方法. 理想情况下,对任何线程池执行程序而言,期望如下: 预先创建了一组初始线程(核心线程 ...
- postman接口测试工具的常规使用
目录 postman接口测试工具简介与安装 postman发送get请求 JSON数据详解 postman发送post请求 postman中post请求传参说明 postman设置请求的header ...
- SpringAOP在web应用中的使用
之前的aop是通过手动创建代理类来进行通知的,但是在日常开发中,我们并不愿意在代码中硬编码这些代理类,我们更愿意使用DI和IOC来管理aop代理类.Spring为我们提供了以下方式来使用aop框架 一 ...
- django基础之day09,手机号校验的规则和代码编写
通过re模块实现手机号码校验的脚本--json老师 import re 通过re模块实现手机号码校验的脚本--json老师 def mobile_validate(value): mobile_re ...
- 《Java基础知识》Java this关键字详解
this 关键字用来表示当前对象本身,或当前类的一个实例,通过this可以调用对象的所有方法和属性. 例如: public class Demo { private int x = 10; priva ...