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设置新生代最大内存大小
    • 这个参数一般使用默认即可
java 复制代码
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter05>jinfo -flag SurvivorRatio 8112
-XX:SurvivorRatio=8

设置-XX:NewRatio=2 -Xms512m -Xmx512m,如生命周期比较长的对象多时,建议调大老年代对象比例

java 复制代码
//先通过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
    关于垃圾回收:频繁在新生区收集,很少在养老区收集,几乎不在永久区/元空间收集

java 复制代码
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)
相关推荐
打球她不香吗1 小时前
本周ALLegro学习内容的总结
学习·allegro
数智化转型推荐官1 小时前
2026统一身份管理系统五大发展趋势解读
java·运维·微服务
看菜鸡互1 小时前
探索用 SlideML 让大模型生成 PPT 的实验方法
java·运维
其实防守也摸鱼2 小时前
蓝队相关知识学习(1)---常用堡垒机和服务器
服务器·功能测试·学习·网络安全·网络攻击模型·攻防对抗·蓝队
冰可乐配2 小时前
fmpeg音频编码组件aac(Advanced Audio Coding (AAC) encoder)学习
学习·音视频·aac
憧憬成为java架构高手的小白2 小时前
MySQl学习
学习
程序员张33 小时前
SpringBoot集成BCrypt密码加密库
java·spring boot·后端
闲猫3 小时前
Spring AI Agentic 模式(第1部分):Agent Skills——模块化、可复用的能力
java·人工智能·spring
源图客3 小时前
云途物流API开发-鉴权认证(Java)
java·网络·python
liguojun20253 小时前
篮球馆自动计时收费系统:从规则配置到自动结算的全流程拆解
java·大数据·运维·人工智能·物联网·1024程序员节