0
点赞
收藏
分享

微信扫一扫

米哈游的春招实习面经,问的很基础

八怪不姓丑 2023-05-10 阅读 86

写在前面

本文一起看下jvm图形化相关的工具,图形化的工具相比于命令行工具的好处是更加直观,也更容易分析问题。

1:jconsole

1.1:准备要连接的jvm进程

定义如下的类;

package a.b;
import java.util.concurrent.*;

public class JsoncoleTest {
	private static CountDownLatch cdl = new CountDownLatch(1);
	
	public static void main(String[] args) throws Exception {
		System.out.println("JsoncoleTest run...");
		cdl.await();
	}
}

然后编译并且运行:

bogon:temp xb$ javac -d . JsoncoleTest.java 
bogon:temp xb$ java a.b.JsoncoleTest
JsoncoleTest run...

1.2:运行jconsole

直接在命令执行jsoncole,即可打开,如下:

在这里插入图片描述

可以看到本地进程远程进程,这里我们连接前面创建本地JVM进程,双击即可进入,如下:

在这里插入图片描述

主要包括的tab签有概览,内存,线程,类,VM概要,分别来看下。

1.3:概览

在概览展示了堆内存的使用量,线程个数,加载类的个数,CPU使用量等信息,具体的我们通过后边内容来看。

1.4:内存

jconsole将内存区域分为堆和非堆,其中非堆主要包括Metaspace元数据区(对jvm的方法区规范的实现,存储类信息,方法信息,常量信息等),以及其他内存区域。如下图:

在这里插入图片描述

1.5:线程

展示线程的数量信息和详细列表信息,作用同jstack -l,如下:

在这里插入图片描述

将我们前面的类修改为如下;

package a.b;
import java.util.concurrent.*;

public class JsoncoleTest {
	private static CountDownLatch cdl = new CountDownLatch(1);
	
	public static void main(String[] args) throws Exception {
		System.out.println("JsoncoleTest run...");
		for (int i = 0; i < 100 ; i++) {
			new Thread(() -> {try {
				Thread.sleep(90000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}}, "xxxx" + i).start();
			Thread.sleep(1000);
		}
		cdl.await();
	}
}

则可以看到线程数量在不断的增多:

在这里插入图片描述

1.6:类

以加载的类的个数信息,当类定义如下时加载的类的个数是2182:

package a.b;
import java.util.concurrent.CountDownLatch;

public class JsoncoleTest {
	private static CountDownLatch cdl = new CountDownLatch(1);
	
	public static void main(String[] args) throws Exception {
		System.out.println("JsoncoleTest run...");
		cdl.await();
	}
}

在这里插入图片描述

1.7:VM概要

VM的概要信息,如加载的类路径信息,类个数信息,堆内存大小信息,运行时间等:

在这里插入图片描述

2:jvisualvm

我们重点看下抽样器,抽样器可以动态的分析堆内存的对象实例信息(jmap -histo的动态版本),以及各个方法的CPU占用信息,分别看下。

2.1:抽样器-内存

首先定义测试类,如下:

package a.b;

import java.util.*;
import java.util.concurrent.*;

public class JvisualVmTest {
	static List<JvisualVmTest> list1 = new ArrayList();
	static CountDownLatch cdl = new CountDownLatch(1);
	public static void main(String[] args) throws Exception {
		for (int i=0;i<1000000;i++) {
			list1.add(new JvisualVmTest());
			Thread.sleep(5);
		}
		cdl.await();
	}
}

编译运行:

D:\test>javac -d . JvisualVmTest.java
注: JvisualVmTest.java使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。

D:\test>java -Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.port=8011 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false a.b.JvisualVmTest

连接后点击抽样器->内存:

在这里插入图片描述

进入下图:

在这里插入图片描述

为了方便我们看动态效果,可以使用左下角过滤功能只显示我们要测试的类,如下截图2次可以看到类实例个数的变化:

在这里插入图片描述

在这里插入图片描述

2.2:抽样器-CPU

使用该功能可以动态的查看各个方法执行的CPU占比,如下测试代码:

package a.b;

import java.util.*;
import java.util.concurrent.*;

public class JvisualVmCpuTest {

	static CountDownLatch cdl = new CountDownLatch(1);
	static String num = "";
	public static void main(String[] args) throws Exception {
		new JvisualVmCpuTest().cpuConsume();
		cdl.await();
	}

	public void cpuConsume() {
		final double SPLIT = 0.01;
		final int COUNT = (int) (2 / SPLIT);
		final double PI = Math.PI;
		final int INTERVAL = 200;
		long[] busySpan = new long[COUNT];
		long[] idleSpan = new long[COUNT];
		int half = INTERVAL / 2;
		double radian = 0.0;
		for (int i = 0; i < COUNT; i++) {
			busySpan[i] = (long) (half + (Math.sin(PI * radian) * half));
			idleSpan[i] = INTERVAL - busySpan[i];
			radian += SPLIT;
		}
		long startTime = 0;
		int j = 0;
		while (true) {
			j = j % COUNT;
			startTime = System.currentTimeMillis();
			while (System.currentTimeMillis() - startTime < busySpan[j])
				;
			try {
				if(idleSpan[j]<70){
					Thread.sleep(idleSpan[j]);
				}
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			j++;
		}
	}
}

编译运行:

D:\test>javac -d . JvisualVmCpuTest.java

D:\test>java -Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.port=8011 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false a.b.JvisualVmCpuTest

连接后,查看抽样器,点击CPU,就可以动态查看CPU占用信息了:

在这里插入图片描述

写在后面

参考文章列表

方法区、永久代、元空间的区别 。

使用Java故意消耗Cpu和内存的代码 。

举报

相关推荐

0 条评论