2013-12-08 104 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對象的大小? –