JVM笔记1

查pid
ps -ef|grep 项目名

查jvm堆配置,和当前java进程堆使用情况
jmap -heap pid

查当前java栈信息
jstack -l pid

jstat -gcutil -pid
查看gc信息(执行多少次fullgc,多少次younggc啥的)

jvisualvm
一个java自带的可视化界面,可以看cpu、内存、线程、gc情况,

spring boot admin
可以监听spring boot 项目,spring boot2配置可能比较方便一点,springboot1.X感觉很难受

jvm配置:
-Xms 初始堆大小
-Xmx 最大堆大小,一般Xms和Xmx设置一般大
-Xmn 年轻代大小 年轻代最大尺寸和最小尺寸设置为一个值 -Xmn,与上边那个设置成同一个值一样,可以减少 由当前堆大小不足导致堆内存扩展引起的性能损耗
-XX:NewSize 设置年轻代大小,
-XX:PermSize 永久代大小,java8以后就没了,java7及以前还有,计算内存的时候不算在jvm的heap之内,算是堆内存之外的一块儿内存
-Xss 每个线程的堆栈大小 一般设置为128k或者256k 这个设置的越小,进程中的线程数就越大,但是还是有限制,最大为3000-5000左右,我尝试过设置128,但是项目启动报错,说最小设置223k大概是,然后我就改成256k了,
-XX:NewRatio 设置年轻代大小,设置比例的,如果值为3 代表老年代/年轻代=3,就是年轻代占总内存的1/4
-XX:SurvivorRatio Eden和survivor区的比值,如果取8,就是eden/1个survivor的值为8,所以年轻代的内存分配就是eden:from:to=8:1:1

在配置的时候,有个类似于基础配置的比例,在不知道项目具体情况的时候,可以这么设置,把年轻代设置为总堆内存大小的3/8,永久代如果有的话,就搞成64m一般就够了。然后开始执行程序,比如在仿真或者在线上,跑项目, 打印gc日志,看fullgc的频率和参数,一般fullgc之后,老年代剩余的内存*(3-4)就是老年代比较合适的堆内存大小。还需要关注一下fullgc的频率,网上建议一天不要超过一次fullgc,可以通过调整eden和survivor比例,年轻代大小来控制,还可以调整一个参数,这个参数可以改变对象在年轻代存活的代数。让对象在年轻代多待几代,有可能就挂了,进不了老年代了,可以减轻fullgc的频率。但是也不能设置的太高,因为这样的话,就会有一堆回收不了的对象在from和to的内存里来回复制,非常影响效率。

-Dfile.encoding=UTF-8 //编码格式
 -Xmx1024m //最大堆内存1g
 -Xms1024m //初始堆内存1g
 -Xmn600m // 年轻代600M
 -Xss256k //线程大小256k
 -Xloggc:C:/Users/19527/Desktop/gclog/questionbankGcLog //gc日志路径
 -XX:+PrintGCDetails //打印gc日志
 -XX:+PrintGCDateStamps //打印gc日志时间戳 主要是方便统计到底多久执行一次fullgc

jvm优化效率最高的就是通过jvm参数查出来的那些比如内存泄漏之类的代码逻辑问题,把这种问题解决了,性能上升比较明显,其他的比如参数配置什么的,对性能提高有限。