JVM(六)-- JVM参数命令及工具

JVM参数

标准参数

不会因为Java版本的变化而变化

‐version
‐help
‐server
‐cp

非标准参数

可能会因为Java版本的变化而变化

-X
‐Xint 解释执行
‐Xcomp 第一次使用就编译成本地代码
‐Xmixed 混合模式,JVM自己来决定
-XX
a.Boolean类型
  格式:‐XX:[+‐]<name> +或‐表示启用或者禁用name属性
  比如:‐XX:+UseConcMarkSweepGC 表示启用CMS类型的垃圾回收器
  ‐XX:+UseG1GC 表示启用G1类型的垃圾回收器
b.非Boolean类型
  格式:‐XX<name>=<value>表示name属性的值是value
  比如:‐XX:MaxGCPauseMillis=500
其他参数
‐Xms1000M等价于 ‐XX:InitialHeapSize=1000M
‐Xmx1000M等价于 ‐XX:MaxHeapSize=1000M
‐Xss100等价于 ‐XX:ThreadStackSize=100

常见参数

官网: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

在哪设置

(1)开发工具中设置比如IDEA,eclipse

(2)运行jar包的时候:java -XX:+UseG1GC xxx.jar

(3)中间件比如tomcat,可以在脚本中的进行设置

(4)通过jinfo实时调整某个java进程的参数(参数只有被标记为manageable的flags可以被实时修改)

查看参数

(1)启动java进程时添加+PrintFlagsFinal参数

(2)通过jinfo命令查看

实践

(1)设置堆内存大小和参数打印
   ‐Xmx100M ‐Xms100M ‐XX:+PrintFlagsFinal
(2)查询+PrintFlagsFinal的值
   :=true
(3)查询堆内存大小MaxHeapSize
   := 104857600
(4)换算
   104857600(Byte)/1024=102400(KB)
   102400(KB)/1024=100(MB)
(5)结论
   设置成功,并且104857600是字节单位

常见命令

官网: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.html

jps

jps
jps ‐l

jinfo

jinfo ‐flag name PID               => jinfo -flag UseParallelGC 14184
jinfo ‐flag <name>=<value> PID    
jinfo ‐flags PID                   => 输出全部的参数
jinfo -sysprops PID                => 输出当前 jvm 进行的全部的系统属性

注意事项 :jinfo虽然可以在java程序运行时动态地修改虚拟机参数,但并不是所有的参数都支持动态修改仅限于由java -XX:+PrintFlagsFinal –version查询出来且为manageable的参数

jstat

jstat -class PID 1000 10 查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次
jstat ‐gc PID 1000 10

jstack

jstack PID       =>  jstack是JVM自带的Java堆栈跟踪工具
选项 作用
-F 当正常输出的请求不被响应时,强制输出线程堆栈
-m 如果调用到本地方法的话,可以显示C/C++的堆栈
-l 除堆栈外,显示关于锁的附加信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
死锁案例
public class DeadLockDemo {
    public static void main(String[] args) {
        DeadLock d1 = new DeadLock(true);
        DeadLock d2 = new DeadLock(false);
        Thread t1 = new Thread(d1);
        Thread t2 = new Thread(d2);
        t1.start();
        t2.start();
    }
}

//定义锁对象
class MyLock {
    public static Object obj1 = new Object();
    public static Object obj2 = new Object();
}

//死锁代码
class DeadLock implements Runnable {
    private boolean flag;

    DeadLock(boolean flag) {
        this.flag = flag;
    }

    public void run() {
        if (flag) {
            while (true) {
                synchronized (MyLock.obj1) {
                    System.out.println(Thread.currentThread().getName() + "----if获得obj1锁");
                    synchronized (MyLock.obj2) {
                        System.out.println(Thread.currentThread().getName() + "----if获得obj2锁");
                    }
                }
            }
        } else {
            while (true) {
                synchronized (MyLock.obj2) {
                    System.out.println(Thread.currentThread().getName() + "----否则获得obj2锁");
                    synchronized (MyLock.obj1) {
                        System.out.println(Thread.currentThread().getName() + "----否则获得obj1锁");
                    }
                }
            }
        }
    }
}

jmap

jmap ‐heap PID
jmap ‐dump:format=b,file=heap.hprof PID
‐XX:+HeapDumpOnOutOfMemoryError ‐XX:HeapDumpPath=heap.hprof # 关于dump文件的分析,可以用一些工具

JDK通用工具

jconsole

jconsole工具是JDK自带的可视化监控工具。查看java应用程序的运行概况、监控堆信息、永久区使用

情况、类加载情况等

jvisualvm

可以监控某个java进程的CPU,类,线程等

连接远程java进程

(1)找一台linux机器,并且安装好tomcat

(2)修改bin/catalina.sh文件

JAVA_OPTS="$JAVA_OPTS ‐Dcom.sun.management.jmxremote ‐Djava.rmi.server.hostname=192.168.1.8 
‐Dcom.sun.management.jmxremote.port=8998 ‐Dcom.sun.management.jmxremote.ssl=false
‐Dcom.sun.management.jmxremote.authenticate=true ‐Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
‐Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password"

(3)在conf目录下添加两个文件

jmxremote.password

guest guest
manager manager

jmxremote.access

guest readonly
manager readwrite

(4)授予权限

chmod 600 jmxremote*

(5)启动tomcat并查看日志

./startup.sh
tail ‐f ../logs/catalina.out

(6)查看端口监听情况

lsof ‐i:8080
lsof ‐i:8998

(7)打开本地的jvisualvm,并添加远程连接

(8)右击主机"192.168.1.8",通过“jmx”进行添加,也就是通过JMX技术具体监控远端服务器哪个Java 进程

第三方通用工具Arthas

github:https://github.com/alibaba/arthas

Arthas 是Alibaba开源的Java诊断工具,采用命令行交互模式,是排查jvm相关问题的利器。

(1)下载

curl ‐O https://alibaba.github.io/arthas/arthas‐boot.jar

(2)启动

java ‐jar arthas‐boot.jar

(3)常用命令

version:查看arthas版本号
help:查看命名帮助信息
cls:清空屏幕
session:查看当前会话信息
quit:退出arthas客户端

dashboard:当前进程的实时数据面板
thread:当前JVM的线程堆栈信息
jvm:查看当前JVM的信息
sysprop:查看JVM的系统属性

sc:查看JVM已经加载的类信息
dump:dump已经加载类的byte code到特定目录
jad:反编译指定已加载类的源码

monitor:方法执行监控
watch:方法执行数据观测
trace:方法内部调用路径,并输出方法路径上的每个节点上耗时
stack:输出当前方法被调用的调用路径

内存分析工具

内存分析的专业工具

基于dump下来的问题进行分析 heap.hprof

(1) Eclipse Memory Analyzer Tool(MAT)

https://eclipse.org/mat/downloads.php

Java堆分析器,用于查找内存泄漏

Heap Dump,称为堆转储文件,是Java进程在某个时间内的快照。

它在触发快照的时候保存了很多信息:Java对象和类信息。

(1)获取dump文件

jmap ‐dump:format=b,file=heap.hprof PID
或
‐XX:+HeapDumpOnOutOfMemoryError ‐XX:HeapDumpPath=heap.hprof

(2)Histogram:可以列出内存中的对象、对象个数及大小

Class Name:类名称,java类名
Objects:类的对象的数量,这个对象被创建了多少个
Shallow Heap:一个对象内存的消耗大小,不包含对其他对象的引用
Retained Heap:是shallow Heap的总和,即该对象被GC之后所能回收到内存的总和

(3)右击类名--->List Objects--->with incoming references--->列出该类的实例

(4)右击Java对象名--->Merge Shortest Paths to GC Roots--->exclude all ...--->找到GCRoot以及原因

(5)Leak Suspects:查找并分析内存泄漏的可能原因Leak Suspects:查找并分析内存泄漏的可能原因

 Reports‐‐‐>Leak Suspects‐‐‐>Details

(6)Top Consumers:列出大对象

(2)heaphero.io

官网: https://heaphero.io

(3)Perfma

官网: https://console.perfma.com

GC分析工具

GC日志

可以使用不同的参数设置不同的日志文件,比如

‐XX:+PrintGCDetails ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps ‐Xloggc:D:\gc.log
gcviewer
java ‐jar gcviewer‐1.36‐SNAPSHOT.jar
gceasy

官网: http://gceasy.io

gcplot

官网:https://it.gcplot.com/

docker run ‐d ‐p 8088:80 gcplot/gcplot
http://192.168.1.8:8088
posted @ 2023-01-31 22:33  snail灬  阅读(382)  评论(0编辑  收藏  举报