JVM学习-堆空间(二)

年轻代与老年代
  • 存储在JVM中的Java对象被划分为两类
    • 一类是生命周期较短的瞬时对象,这类对象的创建和消亡都非常迅速
    • 一类对象的生命周期很长,在某些极端情况下还能够与JVM的生命周期保持一致
  • Java堆区进一步细分的话,分为年轻代(YoungGen)和老年代(OldGen)
  • 其中年轻代可以划分为Eden空间、Survior0空间和Survior1空间(或from区和to区)
    在这里插入图片描述
  • 配置新生代和老年代在堆结构的占比
    • 默认-XX:NewRatio=2,表示新生代占1,老年代占2,新生代占整个堆的1/3
    • 可以修改-XX:NewRatio=4,表示新生代1,老年代占4,新生代占整个堆的1/5
  • 新生代当中,默认Eden和Survivor的比例为8:1:1,但使用时比例为6:1:1,运行时需要关闭自适应策略,可能不起作用(-XX:-UseAdaptiveSizePolicy)
    • 显示指定-XX:SurvivorRatio=8可以将比例调整为8:1:1
  • 几乎所有的Java对象是在Eden区被new出来的
  • 绝大多数的Java对象的销毁都在新生代进行
    • IBM公司研究表明,新生代中80%对象都是朝生夕死的
  • 可以通过-Xmn设置新生代最大内存大小
    • 这个参数一般使用默认即可
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter05>jinfo -flag SurvivorRatio 8112
-XX:SurvivorRatio=8

设置-XX:NewRatio=2 -Xms512m -Xmx512m,如生命周期比较长的对象多时,建议调大老年代对象比例
在这里插入图片描述

//先通过jps查看当前进程PID,通过jinfo命令查看进程的NewRation的设置比例
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter05>jinfo -flag NewRatio 10332
-XX:NewRatio=2
对象分配过程

为新对象分配内存是一件非常严谨和复杂的任务,JVM设计者不仅需要考虑内存如何分配,在哪里分配等问题,并且由于内存分配算法与内存回收算法密切相关,所以还需考虑GC执行完内存回收后是否会在内存空间产生内部碎片。

  1. new对象先放伊甸园区。此区有大小限制
  2. 当伊甸园空间满时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁,再加载新的对象放到伊甸园区
  3. 然后将伊甸园中的剩余对象移动到幸存者0区(Survivor0)
  4. 如果再次触发垃圾回收,此时上次幸存下来的放到幸存者0区的,如果没有回收,放到幸存者1区
  5. 如果再次经历垃圾回收,此时会重新放回幸存者0区,接着再去幸存者1区
  6. 啥时候去养老区呢,可以设置次数,默认15次
    • 设置参数:-XX:MaxTenuringThreshold=进行设置
  7. 在养老区,相对悠闲,当养老区内存不足时,再次触发GC:Major GC,进行养老区的内存清理
  8. 若养老区执行了Major GC之后发现依然无法进行对象的保存,就会产生OOM异常
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    针对幸存者s0,s1区的总结:复制之后有交换,谁空谁是to
    关于垃圾回收:频繁在新生区收集,很少在养老区收集,几乎不在永久区/元空间收集

    在这里插入图片描述
public class HeapInstanceTest {
    byte[] buffer = new byte[new Random().nextInt(1024*1024)];
    public static void main(String[] args) {
        List<HeapInstanceTest> list = new ArrayList<>();
        while (true) {
            list.add(new HeapInstanceTest());
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//执行结果
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.chapter06.HeapInstanceTest.<init>(HeapInstanceTest.java:12)
	at com.chapter06.HeapInstanceTest.main(HeapInstanceTest.java:16)

在这里插入图片描述

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值