18

面试常问的,JVM常用参数以及命令,瞧,你又不会了!

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzA3MTUzOTcxOQ%3D%3D&%3Bmid=2452969222&%3Bidx=2&%3Bsn=5097f84c125f5447ff3841d0489c3db0
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方“ 搜云库技术团队 ”关注,选择“ 设为星标

回复“ 1024 ”或 面试题 获取 4T架构师 资料

简介

java启动参数共分为三类

其一是标准参数( - ),所有的JVM实现都必须实现这些参数的功能,而且向后兼容

其二是非标准参数( -X ),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容

其三是非Stable参数( -XX ),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用

调试参数

打印启动参数

可以查看默认参数

打印GC日志

不要用 XX:+UseGCLogFileRotation ,这个会丢失旧的日志文件,而且重启会覆盖当前日志文件:

应该用下面这个

打印ClassLoader日志

这个参数会在控制台打印所有类加载/卸载信息

OOM时Dump内存

OOM时执行脚本(比如重启)

打印JIT时间

方法被编译时打印相关信息

JMX

内存类

JVM设置内存的单位默认是字节(不加单位的情况下)。

也可以在大小后面增加单位,例如:

设置初始新生代大小

设置最大新生代大小

注意: -Xmn 优先级大于-XX:NewRatio

设置Eden/Survivor比例

表示两个Survivor和Edgen区的比,8表示两个Survivor:Eden=2:8,即一个Survivor占新生代的1/10。

计算方式为:

配置:

8也是默认的比例,不过这个比例在Parallel Scavenge(新生代并行回收器,JDK5以后的默认新生代回收器)回收器下是动态的,运行时会出现Eden/Survivor比例和配置的不同 。整编:微信公众号,搜云库技术团队,ID:souyunku

由于与吞吐量关系密切,Parallel Scavenge收集器也经常称为“吞吐量优先”收集器。除上述两个参数之外,Parallel Scavenge收集器还有一个参数-XX:+UseAdaptiveSizePolicy值得关注。这是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)[插图]。如果读者对于收集器运作原来不太了解,手工优化存在困难的时候,使用Parallel Scavenge收集器配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成将是一个不错的选择。只需要把基本的内存数据设置好(如-Xmx设置最大堆),然后使用MaxGCPauseMillis参数(更关注最大停顿时间)或GCTimeRatio (更关注吞吐量)参数给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。

https://docs.oracle.com/javas...

设置老年代大小

老年代大小无法直接设置,只能通过堆大小+分配比例进行调整

新生代老年代大小计算方式为:

设置永久代(PermGen/MetaSpace)大小

初始大小和最大值的区别

初始值(比如 -Xms )为JVM启动是向操作系统申请的内存大小( malloc ),最大值(比如 -Xmx )表示,当使用的内存超过初始值后扩容的最大值

PS: JVM配置了多少内存并不是说启动后就会占用多少物理内存,因为操作系统的内存分配是惰性的。对于已申请的内存虽然会分配地址空间,但并不会直接占用物理内存,真正使用的时候才会映射到实际的物理内存。

GC类

AfyQNnm.png!web

这里说一下PermGen/Metaspace的GC,没有查到官方资料说永久代的固定垃圾回收器,但是在stackoverflow上有人回答到:

所有垃圾回收器都会回收永久代,包括PS/CMS,但并不是每个GC周期都会清理永久代。

这个不用纠结,看GC日志里清理的信息即可。

Serial/Serial Old

最古老的,单线程,独占式,成熟,每次GC会STW,适合单CPU 服务器

Serial是一个新生代收集器,Serial Old是Serial收集器的的老年代版本

新生代和老年代都用串行收集器

新生代使用ParallerGC,老年代使用Serial Old

ParNew

和Serial基本没区别,唯一的区别:多线程,多CPU的,停顿时间比Serial少

新生代使用ParNew,老年代使用Serial Old

Parallel Scavenge(ParallerGC)/Parallel Old

关注吞吐量的垃圾收集器,高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务 。整编:微信公众号,搜云库技术团队,ID:souyunku

所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

Parallel Scavenge是一个新生代收集器,Parallel Old是Parallel Scavenge收集器的的老年代版本

新生代使用ParallerGC,老年代使用Parallel Old

Concurrent Mark Sweep (CMS)

CMS(Concurrent Mark Sweep),收集器是一种以获取最短回收停顿时间为目标的收集器,一个老年代垃圾回收器。目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。CMS收集器就非常符合这类应用的需求。

新生代使用ParNew,老年代的用CMS

G1

使用G1收集器

垃圾回收器的组合

uMve6bQ.png!web

下面是一些缺省的写法

6rEBJfM.png!web

JDK8

关于G1,虽然说JDK8中已经支持G1了,但是并不是说一定需要。

G1的重要特点是为用户的应用程序的提供一个低GC延时和大内存GC的解决方案,适用于大内存场景(官方推荐堆6G以上)

如果程序正在使用CMS或ParallelOld垃圾回收器,并且具有一个或多个以下特征,那么则可以考虑升级为G1:

  • Full GC持续时间太长或太频繁

  • 对象分配率或年轻代升级老年代很频繁

  • 垃圾收集时间或压缩暂停(超过0.5至1秒)时间过长

PS:如果正在使用CMS或ParallelOld收集器,并且程序没有遇到长时间的垃圾收集暂停,那么就不需要升级到G1

作者: 空无

来源:http://suo.im/5Y8mTF

近期技术热文

1、 能让 Java 应用 CPU 使用率飙升至 100% 的原因  

2、 阿里 神器 Arthas,定位线上BUG,超给力!  

3、 线上环境,线程池BUG,让我怀疑GC机制?  

4、 你连HTTPS 原理没搞懂? 还跟我谈“中间人攻击” 

5、 Spring 和 SpringBoot 比较,解惑区别!  

6、 看这儿,教你怎么从Java8升级到Java11

Qv6ru2I.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK