博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Instrumentation: querying the memory usage of a Java object
阅读量:5370 次
发布时间:2019-06-15

本文共 5644 字,大约阅读时间需要 18 分钟。

Copy from: 

 

Instrumentation: querying the memory usage of a Java object

The most reliable— but not necessarily the easiest— way to estimate the usage of a Java object is to ask the JVM. Querying the JVM for the memory usage of an object requires the Instrumentation framework introduced in Java 5. Hotspot supports the instrumentation framework; if you use a VM from a different vendor, it will need to provide similar support, and there may be some variation in the procedures described here. The general idea is:

  • we create a special agent class with a special premain method, generally compiling it against the rest of our code so that it can see the definitions of the classes whose memory usage we're interested in measuring;
  • the JVM passes a special Instrumentation object to our premain method, which we can use to query the size of an object;
  • we package the compiled agent class into a jar with a special manifest file;
  • we run our program, passing in the agent jar to the VM command line arguments.

On the rest of this page, we'll go through the above procedure step by step.

1. Creating the instrumentation agent class

An instrumentation agent is a class with a special method, with a predefined signature, that the JVM will invoke before the rest of the application for you to set up any instrumentation code. Generally, instrumentation is the act of transforming classes for profiling purposes: for example, we could manipulate the definition of the String class to increment a counter every time a string is created, and thus measure e.g. how many strings per second our application creates. But an interesting additional feature provided by the instrumentation framework is the ability to measure the memory usage of an object.

Our agent is simply a class with the following method defined:

public static void premain(String args, Instrumentation inst) {  ...}

The JVM will pass to our method an implementation of the Instrumentation interface, defined in java.lang.instrument. In turn, this interface defines the method getObjectSize(). So for example, if we want to measure the memory usage of an instance of SomeClass, our agent code would look as follows:

import java.lang.instrument.*;import com.somepackage.SomeClass;public class MyAgent {  public static void premain(String args, Instrumentation inst) {    SomeClass obj = new SomeClass();    long size = inst.getObjectSize(obj);    System.out.println("Bytes used by object: " + size);  }}

Note that there's no interface that our agent needs to define: we just need to make sure that we get the method signature correct so that the JVM will find it.

2. Package the agent into a jar

Once we have compiled our agent class, we need to package it into a jar. This step is slightly fiddly, because we also need to create a manifest file. The latter is simple a text file containing a single line that specifies the agent class. For example, you can create a file called manifest.txt with the following line:

Premain-Class: mypackage.MyAgent

Then, to create the jar, we execute the following command (it's usually worth creating a batch file or shell script with this line in case you need to re-build the agent jar several times):

jar -cmf manifest.txt agent.jar mypackage/MyAgent.class

3. Run the application with the agent

Now, we execute the application as usual, but use the javaagent command line argument to specify that we want to attach our instrumentation agent. For example, assuming the classpath is the current directory and that the application's main method is in com.mypackage.Main:

java -javaagent:agent.jar -cp . com.mypackage.Main

Now, before our application is run, our agent's premain method will be run. And in this case, the size of an instance of SomeClass will be created.

Accessing the Instrumentation object from within our application

In our simple example above, we measured the size of an object created during the execution of the premain method. But what if we want to measure the size of an object during the lifetime of the application? Well, we can still do so; we just need to arrange for the rest of our application to see theInstrumentation object passed to the premain method. This works because the single agent class (and the Instrumentation instance) created at startup remains valid throughout the application. So we can simple store the Instrumentation instance in a static variable, then provide a static method to access it. For example:

public class MyAgent {  private static volatile Instrumentation globalInstr;  public static void premain(String args, Instrumentation inst) {    globalInstr = inst;  }  public static long getObjectSize(Object obj) {
if (globalInstr == null) throw new IllegalStateException("Agent not initted"); return globalInstr.getObjectSize(obj); }}

Now, provided the agent is included in the JVM command line parameters as above, then from anywhere in our application we can callMyAgent.getObjectSize() to query the memory size of an object created by our Java application.

Calculating "deep" memory usage of an object

Note that the getObjectSize() method does not include the memory used by other objects referenced by the object passed in. For example, if Object A has a reference to Object B, then Object A's reported memory usage will include only the bytes needed for the reference to Object B (usually 4 bytes), not the actual object.

To get a "deep" count of the memory usage of an object (i.e. which includes "subobjects" or objects referred to by the "main" object), then you can use the  available for beta download from this site.

转载于:https://www.cnblogs.com/hellotech/p/3952878.html

你可能感兴趣的文章
c#接口
查看>>
MyEclipse部署Jboss出现java.lang.OutOfMemoryError: PermGen space
查看>>
ZOJ 1133
查看>>
alibaba / zeus 安装 图解
查看>>
Planned Delivery Time as Work Days (SCN discussion)
查看>>
Ubuntu:让桌面显示回收站
查看>>
Android上传头像代码,相机,相册,裁剪
查看>>
git 安装体验
查看>>
Oracle 给已创建的表增加自增长列
查看>>
《DSP using MATLAB》Problem 2.17
查看>>
if 循环
查看>>
uva 111 History Grading(lcs)
查看>>
Python学习week2-python介绍与pyenv安装
查看>>
php判断网页是否gzip压缩
查看>>
一个有意思的js实例,你会吗??[原创]
查看>>
sql server中bit字段实现取反操作
查看>>
Part3_lesson2---ARM指令分类学习
查看>>
jQuery拖拽原理实例
查看>>
JavaScript 技巧与高级特性
查看>>
Uva 11729 Commando War
查看>>