JVM调优和GC过程分析

本文详细介绍了JVM模型,包括方法区、栈和堆的结构,重点讨论了Young Generation、Old Generation、Metaspace以及MinorGC和MajorGC/FullGC的工作原理。此外,还分析了JVM调优的常见问题,如内存泄漏导致的Full GC、年轻代GC时间长等,并列举了JVM调优的关键参数,如-Xms、-Xmx、-XX:MaxTenuringThreshold等。最后,提到了JVM性能调优的工具及其在面对频繁Full GC时的应对策略。
摘要由CSDN通过智能技术生成

目录

JVM模型

方法区

Young Generation和MinorGC

Permanent Generation(Metaspace)

Old Generation和MajorGC(FullGC)

判断对象是否要回收的方法

JVM常见问题分析思路

内存泄漏导致的频繁Full GC

年轻代GC时间较长

survivor区两部分空间都是空

元空间设置不当引起的频繁Full GC (Metadata GC Threshold)

频繁发生MinorGC

JVM调优常用参数

-Xms, –Xmx, –Xss,-Xmn(-XX:newSize和-XX:MaxnewSize)

年轻代对象年龄阀值 -XX:MaxTenuringThreshold 

元空间参数 XX:MetaspaceSize,-XX:MaxMetaspaceSize

GC收集器配置

JVM性能调优的工具:

频繁full GC时怎么办


JVM模型

方法区

又叫静态区,被所有的线程共享;方法区包含所有的class和static变量;方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

Java中一个线程一个栈区,每一个栈中的元素都是私有的,不被其他栈所访问。栈有后进先出的特点,栈中的数据大小与生存期都是确定的,缺乏灵活性,但是,存取速度比堆要快,仅次于CPU中的寄存器。java中的8中基本数据类型,局部变量都是存在栈中,也可以理解为这些数据大小基本都是固定的。

Java中只有一个堆,被所有线程共享。简单说就是new出来的对象和数组都存在堆中,大小是可以动态变化的,也正是因为这个原因导致堆中数据访问速度慢。垃圾回收机制检测到某对象未被引用时,则自动销毁该对象。java中的包装数据类型包括Byte、Short、Integer、Long、Float、Double、Boolean、Character这些数据类型都是存放在堆中的

在JDK8之前:Young Generation(Eden、From、To)、OldGeneration、Permanent Generation(JDK8以后改为Metaspace)。

Young Generation和MinorGC

Young Generation:指的是新生带,新生代存储的是新创建的对象。新生代分为较大的Eden空间和两份较小的Survivor空间,默认比例是8:1:1。JVM只会使用Eden和其中一块Survivor空间放新创建的对象,另一份用于GC。

MinorGC:当Eden和其中一块Survivor区空间不足时会触发Minor GC 使用复制清除算法(Copinng算法),原因是年轻代每次GC都要回收大部分对象。MinorGC要做的事就是把存活的对象放到未使用的Survivor区空间中,清空Eden和刚才使用过的Survivor空间(第一次MinorGC只会清空Eden区)。

详细分析过程如下:首先新创建对象会被放在Eden区,当Eden区空闲不够大时JVM为新对象分配空间失败Allocation Failure)引发第一次MinorGC,根据GC算法把存活的对象复制到Survivor中的其中一个S0区,清空了Eden区;然后新创建对象继续放入清空后的Eden区,当Eden区再次被占满之后引发第二次MinorGC,这时候会把Eden区和S0区存活下来的对象移到S1区,然后再继续把新创建的对象放入Eden区,当再次沾满后引发第三次MinorGC,这次会把Eden区和S1区存活的对象复制到S0区,就这样反复GC,每GC一次,对象的年龄就增加一岁,达到某个值后(15),对象会被复制到OldGeneration。新生代中最多只有一个S区被占用(第一次GC前两个都空闲),这种流程回收避免的全部区域回收,提高了效率。

Permanent Generation(Metaspace)

持久带,主要是存放方法区。JDK8以后,Oralce-Sun Hotspot中移除了持久代,用Metaspace代替,元空间的本质和永久代类似,都是对JVM规范中方法区的实现两者的区别是Metaspace是在系统本地内存,它不在于JVM内;

也就是这时候的JVM堆空间大小 = Young Generation + OldGeneration

使用Metaspace代替永久带的原因

永久带的初始化内存-XX:MaxPermSize可能不够用,又不易调整;

Metaspace不在JVM内,避免了GC时候的扫描;

Old Generation和MajorGC(FullGC)

Old Generation指的是老年代,正常情况下,老年代存放的一般是长期存活下来的对象(多次MinorGC后对象年龄达到指定阈值进入老年代))以及大对象(为了避免频繁复制,大对象会直接进入老年代),除此之外,如果survivor 区设置的太小<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WannaRunning

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值