JVM参数

常见参数

java启动参数
参数说明
-所有jvm实现都必须实现这些参数的功能,向后兼容
-X默认jvm实现这些参数的功能,不保证所有jvm实现都满足,不保证向后兼容
-XX各个jvm实现有所不同,可能会随时取消
输出jvm的信息参数
参数说明
-verbose:gc输出每次GC的相关信息
-XX:+PrintGCDetails获取的信息比上面更多
更多信息
参数说明
-XX:PrintGCTimeStamps显示jvm启动到执行GC时流逝的时间,单位是秒
-XX:PrintDateTimeStamps显示执行GC时的本地时间(Java 6 update 4才开始支持)
-Xloggc:/Users/cc/Desktop/log.txtgc信息重定向到文件
解读log信息
CommandLine flags: -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=2147483648 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
0.465: [GC (System.gc()) [PSYoungGen: 5341K->851K(38400K)] 5341K->859K(125952K), 0.0020406 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
0.467: [Full GC (System.gc()) [PSYoungGen: 851K->0K(38400K)] [ParOldGen: 8K->778K(87552K)] 859K->778K(125952K), [Metaspace: 3653K->3653K(1056768K)], 0.0064182 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 38400K, used 1553K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
  eden space 33280K, 4% used [0x0000000795580000,0x00000007957045f8,0x0000000797600000)
  from space 5120K, 0% used [0x0000000797600000,0x0000000797600000,0x0000000797b00000)
  to   space 5120K, 0% used [0x0000000797b00000,0x0000000797b00000,0x0000000798000000)
 ParOldGen       total 87552K, used 778K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
  object space 87552K, 0% used [0x0000000740000000,0x00000007400c2ab8,0x0000000745580000)
 Metaspace       used 3775K, capacity 4888K, committed 5120K, reserved 1056768K
  class space    used 419K, capacity 456K, committed 512K, reserved 1048576K
System.out.println(Runtime.getRuntime().maxMemory());           System.out.println(Runtime.getRuntime().freeMemory());          System.out.println(Runtime.getRuntime().totalMemory());

JVM内存结构

这里写图片描述
JVM的内存由栈寄存器和堆构成,堆里面有新生代、老年代和持久代。

Young(年轻代)

分为Eden(伊甸)区,两个survivor(存活)区。大部分对象(刚new出的对象)在Eden区,当Eden区满时,还存货的对象被复制到survivor区中的一个,当这个survivor区满时,此区的存活对象将被复制到另外一个survivor区,当这个survivor区满时,从第一个survivor区复制过来的并且此时还存活的对象,被复制到“老年代”。survivor总有一个是空的。

Tenured(老年代)

老年代存放从年轻代存活的对象,一般来说老年代存放的都是生命周期较长的对象

Perm(持久代)

用于存放静态文件,如java类,方法。持久代对垃圾回收没有显著影响.final修饰的常量,classLoader加载的信息。

GC的两种类型

ScavengeGC(Minor GC)Full GC
一般情况下,当新对象生成并且在Eden申请空间失败时,触发scavengeGC,堆Eden区域进行GC,清楚非存活对象,并将尚且存活的对象移动到survivor区,然后整理survivor的两个区对整个堆进行真理,包括young tenured和perm。
触发:Eden区满触发full gc的三种原因:tenured被写满;perm被写满;System.gc()被显式调用
新生代发生的垃圾回收操作,因为java对象大多具有朝生夕灭的特性,所以minorGC非常频繁,一般回收速度也比较快,通常在百毫秒级老年代GC(FullGC/MajorGC)发生在老年代的GC,出现了MajorGC经常会伴随至少一次的MinorGC(非绝对,在parallelscavenge收集器的手机策略里就有直接进行majorGC的策略选择过程)。majorGC的速度一般会比MinorGC慢10倍以上,1.4G的Old Gen进行一次回收通常需要20-40秒
首次YGC:对Eden区进行垃圾回收,回收后Eden区中依然存活的对象被移入S0 第二次YGC:将s0中的对象复制到s1,并对Eden区和s1进行垃圾回收,回收后Eden区依然存活的对象被移入s1,并将s0中所有的对象清楚,以此类推,在S0/S1中存活次数超过N次(默认15次)的对象移入OldGen,如果S0/S1空间不足,则直接移入Old Gen对young gen,old gen,perm gen进行一次完整的垃圾回收,old gen不在被引用的对象直接销毁,young gen的回收算法同youngGC,perm GEM回收方式为,如果堆中不存在某个类的任何势力,且该类的Class对象没有在任何地方被引用,则该类被回收

虚拟机给每个对象定义了一个对象年龄(Age)计数器,如果对象在Eden出生并经过第一次MinorGC后仍然存活,并且能被survivor容纳的话,将被移动到survivor空间中,并将对象年龄设为1.对象在survivor区中每熬过一次MinorGC,年龄就增加一岁,当它的年龄增加到一定程度(默认为15岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阈值 通过-XX:MaxTenuringThreshhold来设置

jstat -gcutil <pid> <timediff>

用jstat查看jvm内存使用情况

s0s1EOPYGCYGCTFGCFGCTGCT
S0区占用的空间比s1Eden区Old区Perm区YGC的次数YGCtime从程序启动到采用ygc所有的时间/sFGC次数FGC时间/s用于垃圾回收的总时间/s
xiejiangqiongdeMacBook-Pro:~ cc$ jstat -gcutil 5061 1000
Warning: Unresolved Symbol: sun.gc.generation.2.space.0.capacity substituted NaN
Warning: Unresolved Symbol: sun.gc.generation.2.space.0.used substituted NaN
Warning: Unresolved Symbol: sun.gc.generation.2.space.0.capacity substituted NaN
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
 75.66   0.00   0.00  99.7618    2.212     5    2.398    4.610
 73.66   0.00  20.00  65.5818    2.212     5    4.433    6.645
 73.66   0.00  44.00  65.5818    2.212     5    4.433    6.645
 73.66   0.00  64.00  65.5818    2.212     5    4.433    6.645
 73.66   0.00  84.00  65.5818    2.212     5    4.433    6.645
 73.66   0.00 100.00  65.5818    2.212     5    4.433    6.645
  0.00 100.00   8.00  68.2319    2.613     5    4.433    7.046
  0.00 100.00  32.00  68.2319    2.613     5    4.433    7.046
  0.00 100.00  50.00  68.2319    2.613     5    4.433    7.046
  0.00 100.00  68.00  68.2319    2.613     5    4.433    7.046
  0.00 100.00  86.00  68.2319    2.613     5    4.433    7.046
  2.72 100.00 100.00  81.5520    2.613     5    4.433    7.046
 51.81   0.00   0.00  88.7020    3.010     6    4.433    7.443
  5.87   0.00   2.00  69.1620    3.010     6    6.121    9.130
  5.87   0.00  30.00  69.1620    3.010     6    6.121    9.130
  5.87   0.00  54.00  69.1620    3.010     6    6.121    9.130

ps -ef | grep java 查看待检测进程的id

uidpidppidcstimettycmd
用户ID进程ID父进程ID开始时间登录方式命令

从我的毕设中大量的FullGC看内存

内存泄露时会发生什么

  1. 某些对象会占用大量的JVM内存,且长时间无法被回收掉。这些长时间无法被回收的对象通常都会在Old Gen中
  2. 由于Old Gen中存在大量无法被回收的对象,每次FullGC只能释放出极少的Old Gen空间,回收处的这少部分Old Gen空间又会很快被占满,这就会导致JVM在频繁地进行FullGC
  3. FullGC很慢,而JVM在做GC时会stop-the-world,在GC时终止JVM的一切工作。所以假设在内存泄露发生时,JVM被迫每40秒做一次FullFC,每次FullGC需要30秒,这就代表JVM只有1/4的时间在正常工作,此时的性能一定是非常慢的
  4. 而随着泄露对象的不断增加,OldGen的可用空间会越来越少,最终JVM会回收不出足够的可用内容以支撑程序的运行,从而导致服务的彻底不可用

通过jstat观察Old Gen内存占用的增长速度,以及GC的频次

  • 如果jstat命令输出的信息表示JVM正在频繁进行FullGC,那么基本而已肯定性能故障的原因是内存泄露

    [Full GC (Ergonomics) 3344336K->3068858K(3749376K), 3.7187515 secs]
    [Full GC (Ergonomics) 3344336K->3091406K(3749376K), 3.2715931 secs]
    [Full GC (Ergonomics) 3344336K->3112195K(3749376K), 3.9227456 secs]
    [Full GC (Ergonomics) 3344336K->3139728K(3749376K), 3.5998555 secs]

参考博客

日志信息解读
IDEA JVM运行参数
JVM参数原理和性能调优
jvm调优总结+jstat分析 很好的总结
java gc的工作原理 minor gc full gc的原理
关于tomcat上的性能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值