1.指定JVM的运行模式
两种模式:client,server
区别:
server模式下
初始堆空间 会大一些
默认使用 并行垃圾回收器
启动 慢 运行 快
Client模式下,相对保守,启动快,运行慢一点
实践:JVM在启动的时候会根据硬件 操作系统自动选择Server 还是 Client
例子:
32bit Windows 都是默认使用 Client JVM
32bit 非windows 系统 在2GB内存,同时有两个cpu以上,默认使用Server
64 bit 机器上,只有Server类型的JVM.因此指定-server,-client仅仅在32bit 机器上生效
- 指定 JIT 编译器模式
Java 是一种解释型语言,即时编译
-Xint表示禁用 JIT, 所有字节码都被解释执行,速度最慢
-Xcomp表示所有字节码首先编译称本地代码,然后执行
-Xmixed 默认模式,混合。 让JIT自行判断(推荐使用)
3.查看Java版本
-version,-showversion
区别:每次运行程序,showversion总是先打印version信息
实践:server下建议开启showversion,因为可能有很多版本的java
4.打印设置的XX 选项
-XX:+PrintCommandLineFlags
-XX:+PrintFlagsInitial
-XX:+PrintFlagsFinal
区别:
第一个总是先打印出来所有XX配置项,再运行程序
第二个是打印出来所有默认值
第三个是打印出来生效的值
例子截图:部分参数
5.各Runtime data Area 内存大小设置
注:JVM启动后,会将参数中设置的数量的内存全部设置为私有,
注:即使扩容前有一部分内存不会被用户代码用到,也不会交给其他进程使用
5-1 Method Area
注:Java8之后没有分代管理的概念,也就是没有永生代,相关设置无效
永生代:
-XX:PermSize=256m
-XX:MaxPermSize=256m
元空间:
-XX:MetaspaceSize
(初始空间)到达该值就会触发垃圾收集器进行类型卸载,GC会自动调整该值
-XX:MaxMetaspaceSize
5-2 : 栈空间
-Xss128k
设置每个线程的栈空间大小
实践:java5之前是256k,之后每个线程大小为1M.
实践:应该根据应用来调整线程所需空间大小,相同物理内存下,数值变大,线程数量变少;操作系统对于一个进程中的线程数量有限制,经验数值:3000-5000;
实践:当该值大于2M,会在很大程度上降低系统性能
5-3:堆空间Heap
-Xmx 3350m
等价于-XX:MaxHeapSize 代表最大堆内存为3550M
-Xms 3550m
等价于-XX:InitialHeapSize 代表初始堆内存
实践:建议与-Xmx的值一致,避免每次垃圾回收后重新分配空间
-Xmn 2g
年轻代初始大小为 2G
实践:在堆内存大小确定下,增加年轻代(Young)必然缩小老年代(Old),关系到垃圾回收,影响系统性能,官方建议为整个堆大小的3/8;
-XX:NewSize=1024m
设置年轻代初始值
-XX:MaxNewSize=1024m
设置年轻代最大值
-XX:SurvivorRatio=4
设置年轻代中Eden区与一个Survivor区的比值(Eden,S0)
实践:设置为4,也就是DEden:4,s0:1,s1:1。所以Survivor占据年轻代1/6
-XX:NewRatio=4
设置老年代与年轻代的比例
实践:设置为4,代表老年代是年轻代的4倍
-XX:PretenureSizeThreadshold=1024;
单位为字节,大于该值的对象直接分配到老年代(只对Serial、ParNew收集器有效)
实践:该属性应该是 -XX:PretenureSizeThreshold
-XX:MaxTenuringThreshold=7
表示一个对象如果在Survivor区域内移动次数的阈值,超过,进入老年代
实践:设置为0,代表不会经过年轻代,直接进入老年代;对于需要大量常驻内存的应用,这样可以提高效率
实践:设置比较大,会在年轻代中停留比较久,增加对象在年轻代中回收的概率,减少Full GC的概率,在一定程度提高服务稳定性
-XX:+PrintTenuringDistribution
注:minorGC就是年轻代进行的垃圾回收,FullGC就是在老年代中进行的
让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布
例子:
Desired survivor size A bytes, new threshold C (max **)
- age 1: *bytes,****total
- age 2: *bytes,****total
- age 3: *bytes, B total
第一行显示Survivor的容量,以及对象被移到老年代的年龄阈值
第二行开始,显示当前Survivor的各个年龄段下对象大小和不大于该年龄的累计总和
如果总和B 大于A ,则会发生对象迁移到老年代
然后进行下一次miniorGC,就会出现年龄增长 age 4,各年龄段有些变量可能会被回收,内存减少;相应的此次被回收的年龄段的值会更新到C处
备注:与这一块相关的选项还有以下
-XX:InitialTenuringThreshold
表示对象被移到老年代的年龄阈值的初始值
-XX:TargetSurvivorRatio
表示MinorGC结束后Survivor区域中占用空间的期望比例
以上参数调整没有标准
实践:如果Survivor中对象的年龄分布显示过多的对象经历了很多次GC都到达了MaxTenuringThreshold,才被移入老年代,说明该值可能过大,或者Survivor的空间过大
实践:MaxTenuringThreshold不是0,大于1的时候,但是很多对象年龄都不大于1,在1的时候就被回收了;需要关注以下期望的Survivor空间:如果对象都没有超过期望的Survivor空间阈值,则说明工作良好;反之,可能都超过了,直接进入老年代,那就不好了,调整;
5-4:直接内存
Direct Memory(直接内存)是在java堆外的、直接向系统申请的内存空间
-XX:MaxDirectMemorySize
指定DirectMemory大小,不指定,默认与堆空间最大值一样
注:在堆空间一定的情况,配置的栈空间越小,可以开启的线程数量就可以越多
6.OutOfMemory(内存溢出,使用满了,盛不下)
程序发生OOM,可以开启一些选项来进行善后工作
打印或者安排一些动作自动执行
-XX:+HeapDumpOnOutOfMemoryError
就是发生后,把heap堆转存dump到文件进行分析,文件名默认为java_pid<pid>.hprof pid是该程序的进程号
-XX:HeapDumpPath=<path>
配合打印来转存,这里应该有足够空间来保存文件
-XX:OnOutOfMemoryError
用来指定一个可以执行的脚本,在发生的时候执行它
例子:
先到这里,后续先不做了