我想获得一个物体的大小。我试着用这个方法:
import java.lang.instrument.Instrumentation;
public class ObjectSizeFetcher {
private static Instrumentation instrumentation;
public static void premain(String args, Instrumentation inst) {
instrumentation = inst;
}
public static long getObjectSize(Object o) {
return instrumentation.getObjectSize(o);
}
}
但它抛出了这个错误:
java.lang.NullPointerException
test.ObjectSizeFetcher.getObjectSize(ObjectSizeFetcher.java:13)
servlet.testObj.doGet(cms.java:55)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176)
org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145)
org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92)
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394)
然而我尝试了jprofiler和MAT,但我无法找到这个对象...
我该怎么办?
答案 0 :(得分:5)
要使用检测获取对象大小,需要将代理加载到jvm中,这里是代理代码和清单
剂 - MANIFEST.MF
Premain-Class: mypackage.Agent
Agent-Class: mypackage.Agent
Can-Retransform-Classes: true
Agent.java
/* Agent.java
javac -cp ".:$JAVA_HOME/lib/tools.jar" -d . Agent.java Test.java && \
jar cfm Agent.jar Agent-MANIFEST.MF mypackage/Agent.class
*/
package mypackage;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class Agent implements ClassFileTransformer {
public static Instrumentation inst;
public static void premain(String agentArgs, Instrumentation inst) {
Agent.inst = inst;
}
public static void agentmain(String agentArgs, Instrumentation inst) {
Agent.inst = inst;
}
public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {
/* returning null means we don't want to change a thing
*/
return null;
}
}
上面的代理允许你这个
GetObjectSizeTest.java
package mypackage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public final class GetObjectSizeTest extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body bgcolor=white>");
writer.println("<p>The size of System.in is " + Agent.inst.getObjectSize(System.in) + "</p>");
writer.println("</body>");
writer.println("</html>");
}
}
为了使用tomcat和eclipse你可以参考Adding -javaagent to Tomcat 6 server, where do I put it and in what format?和How to set JVM arguments in tomcat that work both in eclipse and using the startup.bat
答案 1 :(得分:0)
请参阅documentation。摘录:
代理JAR文件的清单必须包含属性
Premain-Class
。此属性的值是代理类的名称。代理类必须实现与主应用程序入口点原则上类似的public static premain
方法。
无法将Java代理提供给已经运行的JVM; premain
方法在main
方法之前被称为,同样明确记录:
在初始化Java虚拟机(JVM)之后,将按指定代理的顺序调用每个
premain
方法,然后将调用实际应用程序main
方法。