JVM系列(二) Java 堆内存分析
创始人
2025-05-31 11:47:35
0

Java 堆内存分析

堆是GC(垃圾收集器)执行垃圾回收的重点区域, 所以今天我们着重讲下堆内存

自己的项目,如果出现OOM或者出现内存泄露,一定是出在堆内存上,因为堆是JVM中最大的一块内存空间,所有线程共享Java堆,物理上不连续的逻辑上连续的内存空间,几乎所有的实例都在这里分配内存,在方法结束后,堆中的对象不会马上删除,仅仅在垃圾收集的时候被删除

1.JVM堆内存结构

堆的内存结构如下:
image.png

如果把JVM的堆 划分区间展开来说, 就是下面的图

image.png

Java7及以前将堆空间逻辑上分成三部分:

  • 新生区 eden+from+to
    • 年轻代又分为Eden和Survivor区。Survivor区由FromSpace和ToSpace组成。Eden区占大容量,Survivor两个区占小容量,默认比例是8:1:1
  • 老年区 Old
    • 较大的对象数据,年轻代存不下会放入老年代
    • 存活很久,没有被清除掉的对象也会放入老年代
  • 永久代 Perm
    • 永久代,也称为方法区,存储程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等

Java8及以后将堆内存逻辑上分为:

  • 新生区 eden+from+to
    • 还是原来的逻辑新生代
  • 老年区 Old
  • 元空间 Metaspace
    • JDK1.8版本废弃了永久代,替代的是元空间(MetaSpace)
    • 元空间与永久代上类似,都是方法区的实现
    • 他们最大区别是:元空间并不在JVM中,而是使用本地内存
    • 参数-MetaspaceSize :初始化元空间大小,控制发生GC阈值
    • 参数-MaxMetaspaceSize : 限制元空间大小上限,防止异常占用过多物理内存

2.Java堆对象分代

为什么根据对象要分代 ?
将对象根据存活概率进行分类,对存活时间长的对象,放到固定区,从而减少扫描垃圾时间及GC频率。针对分类进行不同的垃圾回收算法,对算法扬长避短。

具体怎么分代?
JVM内存划分为堆内存和非堆内存,堆内存分为年轻代(Young Generation)、老年代(Old Generation),非堆内存就一个永久代(Permanent Generation)

  • 堆大小 = 新生代 + 老年代
    • 堆的大小可通过参数–Xms(堆的初始容量)、-Xmx(堆的最大容量) 来指定。
  • 新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,又称作 from 和 to以示区分。
    • 默认的,Edem : from : to = 8 : 1 : 1 。(可以配置参数 –XX:SurvivorRatio 控制)
  • Eden区 占有 8/10 的新生代空间大小,from-to 各自占用 1/10 的新生代空间大小。
  • JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务
    • 所以无论什么时候,总是有一块 Survivor 区域是空闲着的。
  • 新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间。

为什么survivor分为两块相等大小的幸存空间?
主要为了解决碎片化。如果内存碎片化严重,也就是两个对象占用不连续的内存,已有的连续内存不够新对象存放,就会触发GC

怎么确定对象的归属哪一代

  • 新生成的对象首先放到年轻代Eden区,当Eden空间满了,触发Minor GC 清理年轻代
  • 存活下来的对象移动到Survivor0区,Survivor0区满后触发执行Minor GC 清理老年代
  • Survivor0区存活对象移动到Suvivor1区,这样保证了一段时间内总有一个survivor区为空。
  • 经过多次Minor GC仍然存活的对象移动到老年代。
  • 老年代存储长期存活的对象,占满时会触发Major GC=Full GC 清理整个堆空间,包括年轻代和永久代
  • GC期间会停止所有线程任务 STW , 等待GC完成,所以对响应要求高的应用尽量减少发生Major GC,避免响应超时。

3.JVM堆内存参数

参数示例描述说明
-verbose:gc控制台打印GC参数,一般都是自己测试时候用控制台输出
-XX:+PrintGCDetails触发GC时日志打印详细, 适合 线上,正式服务器打印gc日志
-Xms20M初始堆大小 20M
-Xmx20M最大堆大小20M 一般情况下-Xms和-Xmx这两个值设为相同大小
-Xmn10M新生代最大可用值10M, !!!注意采用 G1收集器不设置该参数
-XX:+PrintGC触发GC时日志打印
-XX:SurvivorRatio=8eden:from:to =8:1:1 也就是可用的也就90%
-XX:+HeapDumpOnOutOfMemoryErroOOM时生成Dump文件 dump文件便于我们分析oom
-XX:NewRatio=2新生代:老年代 = 1:2

有这这些参数,我们就可以在用用程序中配置JVM参数,从而得到我们想要的jvm配置,出了问题的时候也能够很快的定位问题

3.程序配置 打印GC参数及日志

设置JVM运行参数

-verbose:gc -Xms20M -Xmx20M  -Xmn10M -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8

下一篇,我们着重讲下 对内存的垃圾回收算法, 到底什么算堆内的垃圾对象, 垃圾到底是怎么被jvm回收的

上一篇:kubernetes CKA练习

下一篇:Java类和对象

相关内容

热门资讯

走进小城看消费丨江西资溪:低碳...   夏日时节下午4点,江西省抚州市资溪县大觉山景区漂流终点依然热闹。来自南昌的游客余鑫漂流结束后没有...
【中原晨会0625】市场分析专... 来源:市场资讯 (来源:中原证券研究所) 本期重点研报目录 【中原策略】市场分析:电子半导体领涨 ...
南向资金连买4日!低费率+可月... 6月25日早盘,港股红利资产震荡整理。截至11时14分,港股红利低波ETF招商(520550)下跌0...
618成交破百万!紫荆花用一套... 一年一度的618年中大促,是消费市场的晴雨表,也是品牌间最激烈的角力场。当各大品牌在直播间里铆足了劲...
原创 黄... 2026年6月25日的国际金价已经从前期的5500美元高点跌到4200美元下方,累计跌幅超过22%,...
英伟达CEO:Vera Rub... 截至9:38,中证半导体材料设备主题指数(931743)涨2.36%创新高;权重股中,中微公司涨3....
再被催债16亿!“钢铁大王”戴... 澎湃新闻记者 贺梨萍 因“铁本事件”入狱五年的戴国芳重返钢铁行业,但他并没有完成从阶下囚再到“钢铁大...
周三原油价格下跌 随着美国和伊朗在和平谈判中取得进展,越来越多的油轮公开穿越霍尔木兹海峡,原油在战时的价格上涨已经蒸发...
这种蛋白是大脑衰老的开关 这种蛋白是大脑衰老的开关 清晨,假设一位五十岁左右的王女士发现自己常常把手机放在熟悉的抽屉里又找不到...
信通院牵头算力Token出海生... 盘面上,截至11:04,中证科创创业50指数(931643)涨1.68%,创历史新高;权重股中,芯原...
海外 774 亿营收背后:日本... 文 | 游戏价值论 6月23日,彭博社报道了腾讯正在围绕出售多家日本游戏工作室少数股权开展谈判,包...
餐饮“抢人”大战:把店开到公交... 作者 |餐饮老板内参 内参君 医院、公交站、演唱会…餐饮品牌,正在无孔不入 在北京儿童医院,肯德基...
快讯 | 外资扫货!陈翊庭:港... 港交所行政总裁陈翊庭在接受《中国证券报》专访时指出,国际资本对中国资产的看法已彻底扭转,布局中国市场...
2777.77元!A股“股王”... 25日早盘,昨天创下历史新高的A股“股王”联讯仪器,今天上午继续走强,盘中股价再度刷新历史新高。 截...
原创 今... 欧洲自己的媒体直接下结论,欧盟衰退躲不掉,内部分裂拦不住,现在就连欧洲顶尖工业巨头,都偷偷在用中国的...
黄仁勋股东大会放言:本轮AI基... 在当地时间6月24日的英伟达(NVDA.O)2026年度股东大会上,股东批准了该公司全部10名董事会...
国际油价大跌 新华社消息, 纽约原油期货主力合约价格24日盘中跌破每桶70美元,为伊朗战事爆发以来首次。 市场分析...
马云带队插秧,什么信号? 一场别开生面的“务农”,让外界看到了一个不一样的阿里巴巴。 近日,阿里巴巴合伙人、高德董事长刘振飞在...
全球最大产能,最高丰度达99.... 本文转自【科技日报】; 6月23日,高丰度硼-10同位素技术暨产业化成果发布会在山东省东营市举办,全...
黄金大跳水!金饰克价年内暴跌近... 25日,现货黄金盘中震荡,截至发稿,报3985.070美元/盎司,跌0.17%。 当地时间24日,...