当前位置: 首页 > ops >正文

JVM-(7)堆内存逻辑分区

JVM 堆内存逻辑分区

在 JVM内存模型 这篇文章中我们了解了JVM 内存的逻辑分区情况,如下:

在 JVM GC 这篇文章中我们了解到,如果某个对象不再被使用就会被当成垃圾,而新建对象一般分配堆空间内存(大部分情况如此,Java对象在特定条件下可以在栈上分配内存)

哪些情况Java对象可以在栈上分配内存?

分配条件
对象若满足以下条件,JVM会将其分配到栈上:

‌1. 作用域受限‌:对象仅在方法内部使用,未被外部引用(如未作为返回值或被其他线程访问)。
‌2. 小对象‌:通常指几十字节以内的小对象。
‌3. 线程私有‌:仅被当前线程使用,不会跨线程共享。 ‌

优化原理
栈上分配通过逃逸分析技术实现,JVM会分析对象是否可能被外部访问。若确定不会逃逸,则将对象分配到栈中,其生命周期随方法执行结束自动销毁,无需垃圾回收,可提升性能。 ‌

适用场景
‌高频调用场景‌:如高频创建临时对象时,栈上分配可减少GC压力。
‌局部变量‌:如方法内部使用的临时对象。

堆内存逻辑分区

新生代与老年代

堆内存在逻辑上分为 新生代(young)和老年代(old/tenured)

  • 新生代(young):刚new出来的对象存放于此
  • 老年代(old/tenured):垃圾回收了很多次都没有把它回收掉的老对象存放于此

新生代又分为:

  • eden 默认比例是8。新new出来的对象放在eden区。
  • survivor(s0) 默认比例是1。当发生YoungGC时,eden区没有被清除的对象转移至 s0或s1
  • survivor(s1) 默认比例是1。

比如:
① 新建对象存放在eden区,当发生YoungGC时,存活对象转移至s0,eden区内存清空
② 又有新对象,存放在eden区,当发生YoungGC时,eden区存活对象和s0区存活对象转移至s1,eden区和s0区内存清空
③ 如此往复,每次发生 GC 时对象年龄会加一,如果多次GC后对象仍然存活,就把对象放到老年代

几个GC的概念

  • MinorGC/YGC :新生代空间耗尽时触发的垃圾回收。
  • MajorGC/FullGC :在老年代无法继续分配空间时触发,新生代、老年代同时进行垃圾回收。

新生代和老年代使用的垃圾回收算法
新生代存活的对象较少,使用的垃圾回收算法是拷贝算法(Copying)。
老年代活着的对象较多,垃圾回收算法适用标记压缩(Mark Compact)或者标记清除(Mark Sweep)。

为什么新生代垃圾回收使用拷贝算法
① 高效处理高频死亡对象
新生代中约99%的对象会在首次垃圾回收时被清除。复制算法通过将存活对象复制到另一块内存区域,仅需处理少量存活对象即可完成回收,显著提升效率。
② 避免内存碎片
复制算法通过将内存分为两块并交替使用,每次回收时仅清空当前使用的内存块,存活对象迁移到另一块内存。这种机制有效减少内存碎片,避免后续分配大对象时出现空间不足的问题。
③ 优化内存分配
新生代内存空间较小(通常为堆内存的1/6),频繁回收可快速释放空间。复制算法通过空间换时间的方式,以较小的内存浪费(仅使用50%的内存)实现高效回收,满足高频垃圾处理需求。
④ 适应对象生命周期
新生代对象通常生命周期较短,复制算法的快速回收特性与这一特性高度匹配。而老年代对象存活率较高,更适合使用 标记-整理算法 (Mark-Compact)以优化空间利用率。 ‌

一个对象的生命历程-从出生到消亡

① 一个对象被new出来之后,首先尝试进行栈上分配,栈上如果分配不下才会进入eden区;
② eden区经过一次垃圾回收之后进入一个survivor区-s1区;
③ survivor区(s1)经过一次垃圾回收之后又进入另一个survivor区-s2区,同时eden区的某些对象也会跟着进入s2;
④ 当对象年龄到某一个值后,会进入到old区。这个值可以通过以下参数设置:

-XX:MaxTenuringThreshold

通过以下命令,可以查看MaxTenuringThreshold的默认值

java -XX:+PrintFlagsFinal | grep MaxTenuringThreshold

windows通过下面命令查看:

java -XX:+PrintFlagsFinal | findstr /i "MaxTenuringThreshold"


意思是一个存活于新生代的对象如果在发生15次 YoungGC 后还没有被清除,那么这个对象就转移到老年代


垃圾回收器

HotSpot虚拟机提供了多种垃圾回收器,根据JDK版本和应用场景不同,默认及可选回收器有所差异。以下是主要回收器分类及特性:

一、‌分代回收器组合
1. ‌Serial + Serial Old
  • 新生代(Serial):单线程复制算法,适用客户端模式或小内存环境
  • 老年代(Serial Old):单线程标记-整理算法,作为CMS失败时的备选
  • 参数:-XX:+UseSerialGC。
2.‌ ParNew + CMS
  • 新生代(ParNew):多线程版Serial,与CMS配合使用
  • 老年代(CMS):并发标记-清除算法,追求低延迟,但存在内存碎片问题
  • 参数:-XX:+UseParNewGC -XX:+UseConcMarkSweepGC(JDK14后移除)
3. Parallel Scavenge + Parallel Old
  • 新生代(Parallel Scavenge):多线程复制算法,注重吞吐量
  • 老年代(Parallel Old):多线程标记-整理算法,JDK8默认组合
  • 参数:-XX:+UseParallelGC -XX:+UseParallelOldGC
二、‌整堆回收器
1. ‌G1(Garbage-First)
  • 分区式回收,兼顾吞吐与延迟,JDK9+默认回收器
  • 将堆划分为多个Region,优先回收垃圾最多的区域
  • 参数:-XX:+UseG1GC
2. ZGC/Shenandoah
  • ZGC:支持TB级堆,停顿时间<10ms,JDK11+提供
  • Shenandoah:低延迟,与ZGC类似但实现不同
  • 参数:-XX:+UseZGC 或 -XX:+UseShenandoahGC
三、‌版本演进与默认选择‌
  • JDK8‌:默认 Parallel Scavenge + Parallel Old
  • JDK9+‌:默认 G1‌
  • JDK14+‌:移除CMS,推荐G1或ZGC

如何查看当前 jvm 默认使用的垃圾回收器?
使用如下命令:

java -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -version

-XX:+PrintGCDetails:这个选项让Java虚拟机(JVM)在控制台输出垃圾收集的详细信息。这包括每次垃圾收集的类型、发生的时间、持续时间以及堆使用情况等信息。


-XX:+PrintCommandLineFlags:这个选项让JVM在启动时打印出所有传递给JVM的命令行参数,包括默认参数和用户指定的参数。这对于调试和了解JVM是如何被配置的有很大帮助。


-version:这个选项让JVM打印出版本信息,这对于确认正在使用的Java版本是有用的。


执行命令后出现 -XX:+UseParallelGC 表示当前JVM启用了 ‌Parallel Scavenge(新生代) + Parallel Old(老年代)‌ 的垃圾回收器组合

参考(推荐):【GC系列】JVM堆内存分代模型及常见的垃圾回收器

http://www.xdnf.cn/news/18344.html

相关文章:

  • 智能编程中的智能体与 AI 应用:概念、架构与实践场景
  • 【Flutter】Container设置对齐方式会填满父组件剩余空间
  • BaaS(Backend as a Service)技术深度解析:云时代的后端开发革命
  • 数据结构青铜到王者第一话---数据结构基本常识(1)
  • Spring面试宝典:Spring IOC的执行流程解析
  • JavaScript 十六进制与字符串互相转(HEX)
  • 通义千问VL-Plus:当AI“看懂”屏幕,软件测试的OCR时代正式终结!
  • 微信小程序基础Day1
  • iOS 文件管理全景实战 多工具协同提升开发与调试效率
  • ACM模式输入输出
  • mlir CollapseShapeOp ExpandShapeOp的构造
  • 循环神经网络实战:用 LSTM 做中文情感分析(二)
  • Class A 包含字段 x Class B 也包含字段 x,如果判断List<A> lista 和 List<B> listb 有相同的 x?
  • 29、工业网络威胁检测与响应 (IDS 模拟) - /安全与维护组件/industrial-network-ids
  • spark数据缓存机制
  • 云计算下数据隐私保护系统的设计与实现(LW+源码+讲解+部署)
  • [RestGPT] docs | RestBench评估 | 配置与环境
  • 阿里云的centos8 服务器安装MySQL 8.0
  • 【OpenGL】LearnOpenGL学习笔记13 - 深度测试、模板测试
  • Linux CentOS 安装 .net core 3.1
  • 1. 准备工作---数据分析编程 - 从入门到精通
  • 密码学——对称加密, 非对称加密和CA
  • 基于SpringBoot的流浪动物领养管理系统【2026最新】
  • 常见的端口扫描
  • 常德二院全栈国产化信创项目:开启医疗新质生产力的“头雁”之旅
  • Android 定位技术全解析:从基础实现到精准优化
  • 数据大屏全链路质量保障测试
  • 消息中间件(RocketMQ+RabbitMQ+Kafka)
  • C++手撕LRU
  • RocketMQ 消息消费 单个消费和批量消费配置实现对比(Springboot),完整实现示例对比