1、下载arthas(阿尔萨斯)
mkdir /opt/arthas/
cd /opt/arthas/
curl -O https://arthas.aliyun.com/arthas-boot.jar
2、top命令查看系统状况
top命令经常用来监控linux的系统状况,是常用的性能分析工具,能够实时显示系统中各个进程的资源占用情况。
top
从图上看占用最高的就是48712和48714这两个java进程(目前系统是PLM系统,部署了两个工作节点,刚好能对应上)
3、使用arthas查看java进行信息
java -jar arthas-boot.jar
执行完毕后会显示正在运行的java进程,输入进行前对应序号就能查看对应进程信息,其中2和3就是前面top命令看到的两个进程
输入2
输入dashboard,查看当前进程的信息,按ctrl+c
可以中断执行。
通过 thread 命令来获取进程类信息
thread 3508
如果找不到想要的,直接输入thread
,将打印第一页的线程
或者打印最忙的三个线程
thread -n 3
或者 thread --all
, 显示所有匹配的线程
通过 jad 来反编译
jad java.net.SocketInputStream
通过watch命令来查看函数的返回值:
要使用 Arthas 的 watch
命令来监视 java.net.SocketInputStream
类中的 read
方法的输出,你可以按照以下步骤进行操作:
-
首先,使用 Arthas 进入到你的 Java 应用程序的进程中。如果你已经在应用程序中启动了 Arthas Agent,可以直接连接;否则,可以通过
attach
命令连接到目标 Java 进程。 -
执行
watch
命令来监视java.net.SocketInputStream
类中的read
方法。在watch
命令中,你可以指定要监视的方法以及输出的格式。
下面是一个示例命令,用于监视 java.net.SocketInputStream
类中的 read
方法:
watch java.net.SocketInputStream read '{params,returnObj,throwExp}' -x 2
这个命令的含义是:
java.net.SocketInputStream read
:监视java.net.SocketInputStream
类中的read
方法。'{params,returnObj,throwExp}'
:输出参数、返回值和异常信息。-x 2
:展开深度为 2,这样可以查看更多信息。
执行这个命令后,你将能够实时查看 java.net.SocketInputStream
类中 read
方法的输入和输出情况。你可以根据实际需求调整命令参数来查看更多或更少的信息。
需要正在运行的才能监控到输出
jvm的年轻代,什么情况下会往老年代写数据?
在Java虚拟机(JVM)中,堆内存通常分为年轻代(Young Generation)和老年代(Old Generation)。年轻代又进一步分为Eden区和两个Survivor区(S0和S1)。对象在堆中首先分配在年轻代的Eden区中,经过几次Minor GC(Minor Garbage Collection)后,如果对象仍然存活,它们可能会被移动到Survivor区。最终,某些情况下对象会从年轻代移动到老年代。
以下是一些对象从年轻代移动到老年代的常见情况:
-
对象年龄阈值:每个对象在Survivor区中存活的时间会增加它的年龄。当对象的年龄达到一定的阈值(由JVM参数
MaxTenuringThreshold
控制)时,这些对象会被移动到老年代。 -
Survivor区空间不足:如果Survivor区中的空间不足以容纳从Eden区和另一个Survivor区中存活的对象,那么这些对象会被直接晋升到老年代。
-
大对象:如果一个新分配的对象非常大,以至于不能在年轻代中找到足够的连续空间来存放它,JVM可能会直接将这个大对象分配到老年代。这种情况通常由JVM参数
PretenureSizeThreshold
控制。 -
老年代晋升失败:在进行Minor GC时,如果年轻代中的存活对象过多,导致无法全部复制到Survivor区中,超出的部分会被直接移动到老年代。
这些机制确保了年轻代和老年代之间的平衡,并优化了垃圾回收的效率。不同的JVM实现和垃圾回收器(如Parallel GC、G1 GC、CMS等)可能会有不同的细节和参数来控制这些行为。
第二种情况(Survivor区空间不足):
-server -Xms4g -Xmx8g -XX:NewRatio=1 -XX:SurvivorRatio=1 -XX:MaxTenuringThreshold=15 -XX:PermSize=256m -XX:MaxPermSize=512m -Djava.awt.headless=true -Dfile.encoding=GBK
这段参数是用来启动Java虚拟机(JVM)的命令行参数。每个参数都有特定的功能,以下是对这些参数的详细解释:
-
-server
:启用JVM的服务器模式,这种模式优化了JVM的性能,适用于服务器环境。 -
-Xms4g
:设置JVM的初始堆内存大小为4GB。 -
-Xmx8g
:设置JVM的最大堆内存大小为8GB。这意味着堆内存的使用范围是在4GB到8GB之间。 -
-XX:NewRatio=1
:设置新生代(Young Generation)与老年代(Old Generation)之间的比例为1:1。这意味着新生代和老年代的内存分配是相等的。 -
-XX:SurvivorRatio=1
:设置Eden区和Survivor区的比例为1:1。JVM的新生代内存区域分为Eden区和两个Survivor区(S0和S1),这个参数将Eden区和每个Survivor区的大小设置为相等。 -
-XX:MaxTenuringThreshold=15
:设置对象在新生代存活的最大年龄(垃圾回收周期数)为15。超过这个年龄的对象会被晋升到老年代。 -
-XX:PermSize=256m
:设置永久代(PermGen)的初始大小为256MB。永久代存储的是JVM运行时使用的类和方法信息。 -
-XX:MaxPermSize=512m
:设置永久代的最大大小为512MB。 -
-Djava.awt.headless=true
:设置JVM为无头模式,这在服务器环境中非常有用,因为服务器通常没有显示设备。这个参数避免了图形界面的需求。 -
-Dfile.encoding=GBK
:设置文件编码为GBK。这个参数指定了JVM使用的默认字符编码格式。
这些参数的组合可以帮助优化JVM的性能,特别是在高负载的服务器环境中。通过合理地配置内存和垃圾回收策略,可以提高应用程序的响应速度和稳定性。
如果:
-XX:SurvivorRatio=2
:设置Eden区和Survivor区的比例为2:1:1,即Eden区占年轻代的2/4,每个Survivor区占1/4。
对于java6来说,-XX:SurvivorRatio的值必须大于5,即幸存区最大只能设置到-XX:SurvivorRatio=6
,而且设置6的话,jvm经过一次gc后,又会恢复默认
-server -Xms2g -Xmx2g -XX:NewSize=1g -XX:MaxNewSize=1g -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=90 -XX:InitialSurvivorRatio=6 -XX:MaxTenuringThreshold=15 -XX:PermSize=128m -XX:MaxPermSize=256m -Djava.awt.headless=true -Dfile.encoding=GBK
-server -Xms5g -Xmx5g -XX:NewSize=2g -XX:MaxNewSize=2g -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=90 -XX:InitialSurvivorRatio=6 -XX:MaxTenuringThreshold=15 -XX:PermSize=256m -XX:MaxPermSize=512m -Djava.awt.headless=true -Dfile.encoding=GBK