jps,jvm调优_JPS使用_Java虚拟机性能监控与调优实战

引言

    本文针对Java虚拟机对程序性能影响,通过设置不同的Java虚拟机参数来提升程序的性能。首先从Java虚拟机各个性能方面来进行监控,找出Java虚拟机中可能对程序性能影响较大的,然后先通过小实验来证明对程序性能的影响,确定了对程序性能影响较大的指标。最后通过一个实际的项目案例来进行调优,给一定的系统资源下,使网站吞吐量达到最大。


一.监控的指标和工具

jps:虚拟机进程状况工具(JDK自带,安装JDK后配置环境变量,命令行可以直接敲出来)

利用jps工具可以显示当前虚拟机中运行的java进程,并且jps后面可以跟参数,-l是输出主类名,-v可以输出JVM启动时候的参数配置。写了如下一段java代码做了个测试。
package demo.test;

public class TraditionalThread {
	public static void main(String[] args) {
		Thread thread = new Thread() {
			public void run() {
				while (true) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("1:" + Thread.currentThread().getName());
				}
			}
		};
		thread.start();
		Thread thread2 = new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("2:" + Thread.currentThread().getName());
				}
			}
		});
		thread2.start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("Runnable" + Thread.currentThread().getName());
				}

			}
		}) {
			public void run() {
				while (true) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("3:" + Thread.currentThread().getName());
				}
			}
		}.start();
	}
}
运行上面的Java程序,打开windows系统的控制台输入命令:
jps -l
jps监控java运行进程
jsp输出JVM启动时参数
jsp输出JVM启动时参数

    如图所示有个TraditionalThread进程在运行,显示主类的全名,进程号为3048,jps工具本身也是一个java程序,进程号为10388,进程号3048就是main函数所在的进程了。一共有3个进程在运行。如图3.2所示,jsp –v输出了JVM启动加载jdk里面内置的tools.jar等等,JVM的参数配置,堆内存最小为1024M,堆内存最大为1024M,永久代最大
为1024M。

jstat:虚拟机运行时信息监控

jstat是用来监控JVM运行时的状态信息的工具,可以查看JVM中类的装载、堆内存的详细信息、垃圾收集等等。我们编写如下测试代码
package demo.test;

import java.util.ArrayList;
import java.util.List;

public class HeapOOM {
	static class OOMObject {
	}

	public static

			void main(String[] args) {
		List<OOMObject> list = new ArrayList<OOMObject>();
		while (true) {
			list.add(new OOMObject());
		}
	}

}

如图所示,Loaded表示加载了439个类,Bytes表示载入类的合计大小,Unloaded表示卸载类数量为0个,第2个Bytes表示卸载类的大小,Time表示在加载类和卸载类上所花费的时间。

同样通过JPS命令获取进程号,然后通过jstat查看内存回收情况:
S0C表示是s0的大小为580608字节,S1C表示是s1的大小为580608字节,S0U表示是s0区已使用大小为0,S1U表示是s1区已使用大小为222611.2,Eden(EU表示Eden)大小为373248字节,Eden:S1 :S0 = 8:1:1,满足之前的分代内存模型。EU表示Eden已使用373248字节,OC表示老年代大小为3485696个字节,OU表示老年代已使用3485192.3字节。YGC表示新生代发生GC的次数为13次,YGCT表示新生代GC的耗时为17.709秒,FGC表示Full GC的次数为54次,FGCT耗时为888.770秒,GCT表示GC的总耗时为906.479秒。

s0区域使用百分比为0,s1区域使用百分比为0,(E)Eden区域使用大小100%,(O)老年代区域使用大小为99.99% 说明老年代已经溢出了。

jmap:导出堆文件分析

我们继续用上面代码做测试,并且通过设置参数-Xms20m -Xmx20m设置堆内存大小为20M,通过设置参数-XX:+HeapDumpOnOutOfMemoryError让虚拟机在发生内存溢出时将当前的堆内存转存为快照,方面后面对堆内存做分析,甚至可以找出堆内存泄露的原因。还需要用到一款内存分析工具MAT(Memory Analyzer Tool),是一个功能强大、可视化的Java heap内存分析工具,它可以帮助我们分析Java堆内存泄漏和内存消耗的情况。使用MAT内存分析工具对堆内存的使用情况进行分析,堆内存中各个对象的占用内存大小及各个对象的数量一清二楚的,看看是哪个存活的对象阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成内存泄露的对象,从而再去找出内存泄露的代码。


待验证后继续更新。。。
 
暂无评论