Instrumentation 是Java提供的一种能够在程序运行时检查和修改类定义的技术。使用Instrumentation,可以构建一个独立于应用程序的代理程序,检测和协助运行在JVM上的程序,甚至可以修改和替换某些类的定义。
本文尝试用它构建一个代理程序,用于监测Java对象占用的内存大小。
创建代理
- 在项目中创建代理模块ObjectSize。
在任意Java项目中通过New - Module创建一个新的模块ObjectSize。也可以单独创建项目。 - 创建Java代理程序
package org.hbin.jvm.agent;
import java.lang.instrument.Instrumentation;
/**
* @author Haley
* @version 1.0
* 2024/8/23
*/
public class ObjectSizeAgent {
private static Instrumentation inst;
public static void premain(String agentArgs, Instrumentation _inst) {
inst = _inst;
}
public static long sizeOf(Object obj) {
return inst.getObjectSize(obj);
}
}
- 生成代理Jar包
选中当前模块,然后在菜单栏打开依次打开:File - Project Structure,在打开的Project Structure窗口中依次点击:Artifacts - JAR - From modules with dependencies。
选择刚建的Module或项目,然后配置MF文件的目录并保存。
更新MF文件的配置,添加Premain-class,值为刚创建的Class全路径名:
打开菜单栏中的Build - Build Artifact,Build即可。
构建顺利的话,你应该已经看到新生成的Jar文件
使用代理监测
有了这个代理,那应该如何使用呢?其实也很简单,先写一段代码,然后运行它即可。
测试代码
编写一段测试代码,示例如下:
package agant;
import org.hbin.jvm.agent.ObjectSizeAgent;
/**
* @author Haley
* @version 1.0
* 2024/8/23
*/
public class ObjectSizeTest {
public static void main(String[] args) {
System.out.println(ObjectSizeAgent.sizeOf(new Object()));
System.out.println(ObjectSizeAgent.sizeOf(new int[3]));
}
}
因为要用到ObjectSizeAgent,记得先把上面的Module添加到项目依赖中哈
运行配置
运行这个测试前,还要配置代理,需要用到-javaagent:
参数。
-javaagent:/Users/Haley/workspace/kafka/out/artifacts/ObjectSize_jar/ObjectSize.jar
根据你的实际环境修改上述路径
运行效果
总结
利用这个代理可以清晰的看到Java对象占用的内存大小,不过它的功能简单、操作复杂,其实也可以使用现成的JOL(Java Object Layout)来替代。你觉得呢?