JVM调优-VisualVm
VisualVm/ Jconsule远程连接
😃 引用自
首先了解两个概念:
Java RMI:Java远程方法调用,即Java RMI(Java Remote Method Invocation)
Java JMX: Java管理扩展,即Java JMX(Java Management Extensions)
参数解析:
-Djava.rmi.server.hostname=远程服务器ip //配置远程调用主机地址,即jar包运行所在系统的IP地址,不配置则默认使用hosts文件中的值
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=10034 //指定JMX的运行端口,jconsole需要对接的既是该端口
-Dcom.sun.management.jmxremote.ssl=false // 是否允许使用ssl方式接入
-Dcom.sun.management.jmxremote.authenticate=false //是否需要进行身份验证
-Dcom.sun.management.jmxremote.rmi.port=10034
-Dcom.sun.management.jmxremote.local.only=true
第一种方式
java -Djava.rmi.server.hostname=xxx.xxx.xxx.xxx
-Dcom.sun.management.jmxremote.port=8888
-Dcom.sun.management.jmxremote.rmi.port=8888
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Xms1024m -Xmx1024m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:+UseParallelOldGC -XX:+UseParallelGC -XX:+UseAdaptiveSizePolicy -jar xxx.jar
第二种方式:
首先在服务器终端设置环境变量,主要是便于每次启动项目时使用:
export JAVA_OPTS='-Djava.rmi.server.hostname=你的服务器地址(公网ip) -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.rmi.port=8888 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false'
参数和上面一样,就不解释了
导入环境变量后,用命令重新加载配置文件:source /etc/profile;可以直接将export命令写入profile文件最后,在加载文件便可以保持该环境变量一直生效。
切换到你服务器的jvm配置路径:/usr/lib/jvm/…
拷贝jmxremote.password.template文件到jmxremote.pwssword:
添加写入权限:
然后对文件进行修改:vim jmxremote.password
取消最后两行的注释,保存退出。
java 11开启远程GC连接(jstatd配置开启)
vim jstatd-all.policy
配置 jstatd-all.policy:
grant codebase "jrt:/jdk.jstatd" {
permission java.security.AllPermission;
};
grant codebase "jrt:/jdk.internal.jvmstat" {
permission java.security.AllPermission;
};
给jstatd.all.policy文件 执行权限:chmod 777 jstatd.all.policy.
运行命令:./jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.1.249
参数说明:
-J-Djava.security.policy=jstatd.all.policy =号后面的是文件的绝对路径;
-J-Djava.rmi.server.logCalls=true 打开日志,如果客户端有连接过来的请求,可以监控到,便于排错;
-J-Djava.rmi.server.hostname=192.168.1.xxx 指明本机 hostname 对应的本机地址,确保该地址可以给客户机访问。因为有的服务器 hostname 对应的 ip 不一定是外网能连上的,最好在这里直接明确指定;
-p 9999 指定服务的端口号,默认是1099。可选参数。
如果还连不上考虑防火墙拦截了端口,firewall-cmd --list-all,查看一下并暴露对应端口
- 注意此处需查看和jstatd相关的监听端口,涉及两个,使用下面的命令查看**
netstat -antlp|grep jstatd
# netstat -anlp|grep 8888 // 查看端口是否启动
开启相关端口
[root@localhost bin]# firewall-cmd --zone=public --add-port=44136/tcp --permanent
success
[root@localhost bin]# systemctl restart firewalld
查看端口是否开启
连接配置
启动服务,查看对应的端口是否处于监听状态
netstat -apn | grep java 查看监听的端口
VisualVm界面简介
采集GC信息的一些命令
- JConsole, jstat, jinfo, jstack 和 jmap 这些独立的工具,是 Java VisualVM 的一部分。Java VisualVM 通过结合使用这些工具来获取 JVM 的数据信息,进行重新组织,最后以图像的形式进行展示。另外,用户可以通过插件扩展 Java VisualVM 的功能。
RZ xshell传包
lscpu //cpu信息
df -h // 磁盘使用情况
df -Th
ulimit -n // 查看系统允许连接的线程数
crontab -e // 查看定时器
ps -xH|wc -l // 查看正在连接的线程数
ps -mp <PID> 这样可以查看一个进程起的线程数。
top -o %MEM: 由于终端直接输入top命令无法快速查找到占用内存大的进程,所以需要以内存占用大小来排序
jps 虚拟机进程情况
jps -l:输出进程号和jar包名称
jstat 虚拟机运行数据
jstat -gc pid:监视堆的情况,容量、已用空间、GC时长等
jstat -gcutil pid:和-gc差不多,但主要关注已使用空间占总空间的比例
可以后缀时间如:jstatd -gcutil pid 5000,则每5S输出一次
jmap 内存映射
jmap -heap pid:展示堆详细信息,用了哪种回收器、参数配置、分代情况等
jmap -dump:format=b,file=xxx.hprof pid:生成当前时刻堆快照
jmap -dump:live,format=b,file=/export/dump/dump.hd 9326
jstack 堆栈跟踪
jstack pid:生成当前时刻线程快照 threaddump
jstack -l 69239 | grep 'java.lang.Thread.State' | wc -l 统计线程数
top -H -p 4433 查看占用cpu高得线程
printf "%x\n" 4434 转换线程ID 1152
jstack 4433 | grep 1152 -A 30 定位cpu占用线程
可以将信息输出到指定文件如:jmap -hep pid >/xxx/jmapHeap.txt
查看 cpu 占用率高的线程
ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu
查看占用内存最多的程序
ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head
查看占用cpu最多的程序
ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head
垃圾回收器切换
Serial收集器(-XX:+UseSerialGC -XX:+UseSerialOldGC)
启用CMS: -XX:+UseConcMarkSweepGC
Parallel Old启用:-XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy
+UseParallelGC = 新生代ParallelScavenge + 老年代ParallelOld
+UseParallelOldGC = 同上
-UseParallelOldGC = 新生代ParallelScavenge + 老年代SerialOld
改用并行垃圾回收器
-Xms1024m -Xmx1024m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m
-XX:+UseParallelOldGC -XX:+UseParallelGC -XX:+UseAdaptiveSizePolicy
一些垃圾回收器参数
jvm不会把已经申请的内存还给OS, 因为很可能马上又要分配给新的对象,每次向 OS 申请内存是很慢的。所以管理控制台显示的内存使用情况和windows任务管理器中的不一样。jvm中有两个参数 MaxHeapFreeRatio, MinHeapFreeRatio 可以收缩堆,还内存给OS, 但只在client 模式下有效,而且是分次返还,0% on the first call, 10% on the second call, 40%, on the third call, and 100% by the fourth call.
例如:java -client -verbose -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xmx100m -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=30
G1默认垃圾回收参数
-XX:MaxGCPauseMillis 期望的最大GC暂停时间,默认为:200ms。
注意:G1的默认策略是期望在吞吐量与延迟之间保持平衡,所以如果你希望获得较高的吞吐量,那么可以通过减少GC暂停的频率来实现,
而减少GC暂停频率的主要方式就是增加最大GC暂停时间。
-XX:GCPauseTimeInterval 最大暂停时间间隔的目标。默认情况下,G1不设置任何目标,允许G1在极端情况下连续执行垃圾回收。
-XX:ParallelGCThreads垃圾收集暂停期间用于并行工作的最大线程数。默认根据运行JVM计算机的可用线程数决定,计算方式:当进程可用的CPU线程数小于等于8时,则直接使用该数,否则,将设置为:8 + (n - 8) * (5/8) 。在每次暂停时,使用的最大线程数还需要考虑最大堆的限制,即参数:-XX:HeapSizePerGCThread。refinement threads线程数量可以通过-XX:G1ConcRefinementThreads或-XX:ParallelGCThreads参数设置CMS默认启动的回收线程数是:(CPU数量+3) / 4 (2)CMS收集器无法处理浮动垃圾
-XX:ConcGCThreads 用于并发工作的最大线程数,默认情况下,此值为:-XX:ParallelGCThreads除以4。如果你想要能够更快的完成并发标记,则可以适当增加并发标记的线程数量。
-XX:+G1UseAdaptiveIHOP使用自适应IHOP。Initiating Heap Occupancy Percent(触发并发启动收集的阈值),G1通过观察标记需要多长时间以及标记周期期间通常在老年代分配多少内存来自动确定最佳IHOP,此功能称为自适应IHOP。如果此功能开启,则G1将使用-XX:InitiatingHeapOccupancyPercent=45的值做为并发启动收集的阈值。如果G1没有很好的预测出,触发并发标记的老年代占用率,则建议禁用:-XX:-G1UseAdaptiveIHOP,并自行调整-XX:InitiatingHeapOccupancyPercent的阈值
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:./logs/gc.log
CMS默认启动的回收线程数是:(CPU数量+3) / 4
其他的参数
MinHeapFreeRatio = 40
空闲堆空间的最小百分比,计算公式为:HeapFreeRatio =(CurrentFreeHeapSize/CurrentTotalHeapSize) * 100,值的区间为0到100,默认值为 40。如果HeapFreeRatio < MinHeapFreeRatio,则需要进行堆扩容,扩容的时机应该在每次垃圾回收之后。
MaxHeapFreeRatio = 70
空闲堆空间的最大百分比,计算公式为:HeapFreeRatio =(CurrentFreeHeapSize/CurrentTotalHeapSize) * 100,值的区间为0到100,默认值为 70。如果HeapFreeRatio > MaxHeapFreeRatio,则需要进行堆缩容,缩容的时机应该在每次垃圾回收之后。
MaxHeapSize = 4294967296 (4096.0MB)
JVM 堆空间允许的最大值。
NewSize = 1363144 (1.2999954223632812MB)
JVM 新生代堆空间的默认值。
MaxNewSize = 2576351232 (2457.0MB)
JVM 新生代堆空间允许的最大值。
OldSize = 5452592 (5.1999969482421875MB)
JVM 老年代堆空间的默认值。
NewRatio = 2
新生代(2个Survivor区和Eden区 )与老年代(不包括永久区)的堆空间比值,表示新生代:老年代=1:2。
SurvivorRatio = 8
两个Survivor区和Eden区的堆空间比值为 8,表示 S0 : S1 :Eden = 1:1:8。
MetaspaceSize = 21807104 (20.796875MB)
JVM 元空间的默认值。
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
JVM 元空间允许的最大值。
G1HeapRegionSize = 1048576 (1.0MB)
在使用 G1 垃圾回收算法时,JVM 会将 Heap 空间分隔为若干个 Region,该参数用来指定每个 Region 空间的大小。
常用linux命令
1.输入命令按两下tab会有补全
2.vim
/+关键字 ,回车即可。此为从文档当前位置向下查找关键字,按n键查找关键字下一个位置,N上一个
?+关键字,回车即可。此为从文档挡圈位置向上查找关键字,按n键向上查找关键字;
3.systemctl stop crond 停止定时器
4.pidof java 查看所有java 进程pid
5.kill -9 所有java进程pid
6.free -g查看内存占用情况
7.firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --list-all
netstat -anlp|grep 8888 // 查看端口是否启动
netstat -apn | grep java 查看java相关的端口
netstat -antlp|grep jstatd
8.端口被占用
netstat -aon|findstr 443
taskkill /T /F /PID 9088
9.网络配置
cd /etc/sysconfig/network-scripts/
10.清理缓存
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches
11.查找文件
find / -name .erlang.cookie NUVDVFOLUIQBCXRCXHWC