JVM堆内存解析

一、JVM堆内存介绍

Java大多数对象都是存放在堆中,堆内存是完全自动化管理,根据垃圾回收机制不同,Java堆有不同的结构,下面是我们一台生产环境服务器JVM堆内存空间分配情况,JVM只设置了-Xms2048M -Xmx2048M。

1、JVM堆内存为什么要分代

分代目的主要是优化GC的性能,做了分代后在GC时不用对整个堆内存进行扫描,因为Java很多对象是朝生夕死,这部分可以单独放在一个区便于及时回收掉。

2、新生代

**伊甸区(Eden):**新创建的对象先被分配在Eden区存放。

**幸存区1、幸存区2:**当Eden区满的时候进行Minor GC,如果对象还存活的,会被移到幸存区,以后每次GC时对象的年龄会加1,当年龄加到一定程度就会被移到老年代,幸存区分成两个区,每次只使用一个区,当一个区块填满了后会将还活着对象复制到另一个区。

新生代采用复制算法进行垃圾回收,垃圾回收进行的比较频繁,每次执行Minor GC耗时比较短(监测两周数据,每天执行28次Minor GC,每次耗时10毫秒)

3、老年代

老年代对象比较稳定,当有新生代对象移到老年代,如果空间不够时会触发MajorGC,采用标记清除法,即扫描内存区块后标记出存活的对象,然后将未标记的进行回收,MajorGC耗时比较长(监测两周数据,只有启动的时候执行了4次MajorGC,每次耗时200毫秒)。

二、监测堆内存区空间变化

1、使用jstat监测堆内存空间使用情况

使用Shell脚本每隔一分钟获取一次内存占用数据并写入数据库。

2、内存空间使用数据分析

从图中可以看出

1、YGC和EU(伊甸区内存使用大小)的关系,当EU占满了,触发了YGC,然后EU下降。

2、S0和S1空间使用相互切换,当S0空的时候,新生代幸存对象放在S1,当S1空的时候,新生代幸存对象放在S0。

3、老年代的占用空间和FGC

跟踪了从7月13号~7月19号 OU从83M增长为107M,远远达不到分配的1365.5M,另外每周都有系统发布JVM会重启,所以都没有发生过FGC,新系统上线时要特别关注FGC的情况,最常见的是当异常情况下把表的数据全部加载到内存,这种极易造成堆内存快速增长,然后频繁FGC,甚至发生OOM。

三、Java对象在堆中分配的流程图

注:网上找的图片

相关推荐
库森学长7 小时前
面试官:发生OOM后,JVM还能运行吗?
jvm·后端·面试
描绘一抹色9 小时前
JVM基础01(从入门到八股-黑马篇)
jvm
微风粼粼1 天前
程序员在线接单
java·jvm·后端·python·eclipse·tomcat·dubbo
掘金-我是哪吒1 天前
分布式微服务系统架构第158集:JavaPlus技术文档平台日更-JVM基础知识
jvm·分布式·微服务·架构·系统架构
abigalexy1 天前
深入JVM底层-内存分配算法
jvm
weixin_ab2 天前
JMM--数据原子操作
jvm
超级小忍2 天前
JVM 中的垃圾回收算法及垃圾回收器详解
java·jvm
喝可乐的布偶猫2 天前
Java类变量(静态变量)
java·开发语言·jvm
abigalexy2 天前
深入JVM底层-垃圾回收GC算法
jvm
麦兜*3 天前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构