2013-12-08 62 views
3

我想获取对象的大小。我试图用这个方法:获取对象的大小

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) 

但是我tryed的JProfiler和MAT但我无法找到该对象活着......

我能做什么?

+0

的premain当一个代理从Java连接被称为命令行,例如:'-javaagent:agent.jar',你在做这个吗? – alexgirao

+0

@alexgirao不,因为我使用tomcat,我可以这样做吗? –

+0

afaik,当你使用java代理时,你会得到instrumentation对象,一个java代理用来监视jvm,也许这不是获得这个对象的大小的方法 – alexgirao

回答

3

为了得到物体的大小使用仪表,有必要的试剂加载到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

0

请参考documentation。摘录:

The manifest of the agent JAR file must contain the attribute Premain-Class . The value of this attribute is the name of the agent class. The agent class must implement a public static premain method similar in principle to the main application entry point.

Java代理不能促成一个已经运行的JVM;该premain方法在main方法之前调用,再次作为明确记载:

After the Java Virtual Machine (JVM) has initialized, each premain method will be called in the order the agents were specified, then the real application main method will be called.

+0

我的清单是这样的:Manifest-Version:1.0 类路径: Premain-Class:ObjectSizeFetcher但它不工作..我使用tomcat和我是一个web应用程序 –

+0

这是行不通的。代理JAR只能用于主入口点,不能用于部署到已运行的应用程序容器中的Web应用程序。另外,你真的不应该把你的课程放到默认包中。 –

+0

hmmm,所以问题是我如何获得webapp对象的大小? –