jvm复习笔记

 

一、jvm组成部分

名称内容备注
数组,对象、分为新生代、存活区、老年代

新生代:存活区 8:2

新生代:老年代 1:2

 

局部变量表、对象的引用、操作数栈、方法出口 
程序计数器行号指示器、通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成,也就是记录当前线程的执行点,调度线程执行 
方法区类的编译信息,静态变量,常量 
直接内存nio操作

在jdk1.4中新加入了NIO类,他可以调用native函数库直接分配堆外内存,然后通过java堆中的DirectByteBuffer

对象来指向这块内存,进行内存分配等工作。

 
   

二、参数配置

名称参数参数说明

-Xms:堆最小值(新生代,老年代之后)

-Xmx:堆最大值(新生代,老年代之后)

-Xmn指定eden区的大小

-XX:SruvirorRation调整幸存区的大小

-XX:PretenureSizeThreshold设置进入老年代的阈值

例:-Xms1024 -Xmx1024

通常将-Xms与-Xmx设置为一样大小来减小gc的次数,堆内存不足时抛出OutOfMemoryError异常

-Xss

例:-Xss128k

单线程下无论栈帧太大还是栈容量太小,及应用深度超过虚拟机允许深度都会抛出StackOverflowError每个方法压入栈的帧大小是不一致的。多线程下当每个线程分配栈帧太大内存不够扩展时抛出OutOfMemoryError异常线程栈帧越大,可创建的线程越少

方法区

-XX:PermSize方法区内存最小值

-XX:MaxPermSize方法区内存最大值

例: -XX:PermSize=20M

  -XX:MaxPermSize=20M

 

各个线程共享的内存区域,主要用来存储类的元数据、常量、静态变量、即时编译后的代码

异常类型 OutOfMemoryError

原因:常量过多,或代理反射等使用频繁

直接内存-XX:MaxDirectMemorySize

例: -XX:MaxDirectMemorySize=10M

不足时抛出OutOfMemory异常

辅助参数

-XX:+HeapDumpOnOutOfMemoryError 打印堆内存异常时快照信息

-XX:+HeapDumpPath快照输出路径

-

 
   
   
   
   

三、垃圾回收算法

名称优缺点备注
标记--清除算法(Mark-Sweep)

算法执行分为两个阶段标记与清除,所有的回收算法基本都是基于标记回收算法深度优化

缺点:效率问题,内存空间碎片(不连续的空间)

 
复制回收算法(包括分代算法)

比较标记清除算法,避免回收造成的碎片化问题

缺点:以局部的内存空间牺牲为代价,不过空间的浪费比较小,默认8:1比例1是浪费的,复制也有一定的效率与空间成本

 
标记整理算法(Mark-Compact)

避免了空间的浪费,与内存碎片问题

缺点:整理时复制有效率成本

 

四、垃圾收集器

垃圾收集器种类
名称用法备注
Serial(串行GC)-XX:+UseSerialGC

串行收集器采用单线程stop-the-world的方式进行收集。当内存不足时,串行GC设置停顿标识,待所有线程都进入安全点(Safepoint)时,应用线程暂停,串行GC开始工作,采用单线程方式回收空间并整理内存。单线程也意味着复杂度更低、占用内存更少,但同时也意味着不能有效利用多核优势。事实上,串行收集器特别适合堆内存不高、单核甚至双核CPU的场合。
 

Serial Old收集器(串行GC)-XX:+UseSerialGC
ParNew(并行GC)-XX:+UseParNewGC新生代收集器,可以认为是Serial收集器的多线程版本,在多核CPU环境下悠着比Serial更好的表现
Parallel Scavenge(并行回收GC)

-XX:UserParallelGC

-XX:parallelGcThreads=4指定线程数

并行收集器,追求高吞吐量,高效利用CPU。吞吐量一般为99%,吞吐量=用户线程时间/(用户线程时间+GC线程时间)。适合后台应用等对交互响应要求不高的厂家,是server级别默认采用的GC方式
Parallel Old-XX:+UseParallelOldGCParallel Scavenge收集器的老年代版本,并行收集器,吞吐量有限
CMS(并发GC)-XX:+UseConcMarkSweepGC

年轻代ParNew与并行收集器类似,而老年代CMS每个收集周期都要经历:初始标记、并发标记、重新标记、并发清除。其中,初始标记以STW的方式标记所有的根对象;并发标记则同应用线程一起并行,标记出根对象的可达路径;在进行垃圾回收前,CMS再以一个STW进行重新标记,标记那些由mutator线程(指引起数据变化的线程,即应用线程)修改而可能错过的可达对象;最后得到的不可达对象将在并发清除阶段进行回收。值得注意的是,初始标记和重新标记都已优化为多线程执行。CMS非常适合堆内存大、CPU核数多的服务器端应用,也是G1出现之前大型应用的首选收集器。

但是CMS并不完美,它有以下缺点:

由于并发进行,CMS在收集与应用线程会同时会增加对堆内存的占用,也就是说,CMS必须要在老年代堆内存用尽之前完成垃圾回收,否则CMS回收失败时,将触发担保机制,串行老年代收集器将会以STW的方式进行一次GC,从而造成较大停顿时间;
标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩。CMS也提供了参数-XX:CMSFullGCsBeForeCompaction(默认0,即每次都进行内存整理)来指定多少次CMS收集之后,进行一次压缩的Full GC。

G1

-XX:+UseG1GC

-XX:G1HeapRegionSize=n可指定分区大小(1MB~32MB,且必须是2的幂)

 

五、常用组合

常用组合
Serial/Serial Old

年轻代Serial收集器采用单个GC线程实现"复制"算法(包括扫描、复制)

年老代Serial Old收集器采用单个GC线程实现"标记-整理"算法

Serial与Serial Old都会暂停所有用户线程(即STW)

适用场合:

CPU核数<2,物理内存<2G的机器(简单来讲,单CPU,新生代空间较小且对STW时间要求不高的情况下使用)

-XX:UseSerialGC:强制使用该GC组合

-XX:PrintGCApplicationStoppedTime:查看STW时间

ParNew/Serial Old与上边相比,只是比年轻代多了多线程垃圾回收而已
ParNew/CMS当下比较高效的组合
Parallel Scavenge/Parallel Old

自动管理的组合 

年轻代Parallel Scavenge收集器采用多个GC线程实现"复制"算法(包括扫描、复制)年老代Parallel Old收集器采用多个GC线程实现"标记-整理"算ParallelScavenge与Parallel Old都会暂停所有用户线程(即STW)

     适用于 很多的CPU计算任务而用户交互任务较少的情况不想自己去过多的关注GC参数,想让虚拟机自己进行调优工作

G1最先进的收集器,但是需要JDK1.7update14以上
  

六、调优方法

1.预留新生代空间

  由于fullGC的成本远比minorGC的成本打,所以给应用分配一个合理的新生代空间,尽量将对象分配到新生代减少fullGC的频率

2.大对象进入老年代

   将大对象直接分配到老年代,保持新生代对象的结构完整性,以提高GC效率,以通过-XX:PretenureSizeThreshold设置进入老年代的阀值

3.稳定与震荡的堆大小

稳定的对大小是对垃圾回收有利的,方法将-Xms和-Xmx的大小一致

4.吞吐量优先

尽可能减少系统执行垃圾回收的总时间,故采用并行垃圾回收器XX:+UseParallelGC或使用-XX:+UseParallelOldGC

5.减低停顿

使用CMS回收器,同时减少fullGC的次数

七、调优工具

调优工具
jps虚拟机进程状况工具
jstat虚拟机统计信息监视工具
jmapjava内存印象工具
jhat虚拟机堆转储快照分析工具
jstackjava线程堆栈跟踪工具
jinfojava配置信息工具
  

如果各项参数设置合理,系统没有超时日志出现,GC频率不高,CG耗时不高,那么没有必要进行GC优化;如果GC时间超过1-3S,或者平方GC,则必须优化。如果满足下面的指标,则一般不需要进行GC优化:

(1)Minor GC执行时间不到50ms;

  (2)MinorGC执行不频繁,约10秒一次;

  (3)Full GC执行时间不到1s

  (4)FullGC执行平路不算频繁,不低于10分钟1次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值