5

I would like to get the size of an object. I tried to use this method:

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);
    }
}

But it thrown this error:

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)

However I tryed jprofiler and MAT but I'm not able to find this object alive...

what can I do?

Maroun
  • 94,125
  • 30
  • 188
  • 241
Andrea Catania
  • 1,361
  • 3
  • 21
  • 37
  • premain is called when an agent is attached from java command line, e.g.: `-javaagent:agent.jar`, are you doing this? – alexgirao Dec 08 '13 at 09:08
  • @alexgirao no because I working with tomcat, can I do this? – Andrea Catania Dec 08 '13 at 09:11
  • afaik, you get the instrumentation object when you use a java agent, a java agent is used to instrumentate the jvm, maybe this is not the way to get the size of this object – alexgirao Dec 08 '13 at 09:15
  • @alexgirao what is the other way? you have an idea? – Andrea Catania Dec 08 '13 at 09:17
  • that depends on what you are trying to do, if you want the estimation of the object size inside the jvm, then a java agent is the way to go, but I doubt this is what you want to do. what are you trying to do? – alexgirao Dec 08 '13 at 09:21
  • @alexgirao I would like to know the size of my object for try other way to implement my object to the best. If an agent help me ok go for this way :D can you show me please? – Andrea Catania Dec 08 '13 at 09:29
  • you can try http://stackoverflow.com/questions/6697063/adding-javaagent-to-tomcat-6-server-where-do-i-put-it-and-in-what-format and see where it leads – alexgirao Dec 08 '13 at 09:32
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42732/discussion-between-andrea-catania-and-alexgirao) – Andrea Catania Dec 08 '13 at 10:13

2 Answers2

6

To get the object size using instrumentation, it is necessary to load an agent into the jvm, here is agent code and manifest

Agent-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;
    }
}

the agent above allows you this

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>");
    }
}

for this to work with tomcat and eclipse you may refer to Adding -javaagent to Tomcat 6 server, where do I put it and in what format? and How to set JVM arguments in tomcat that work both in eclipse and using the startup.bat

Community
  • 1
  • 1
alexgirao
  • 885
  • 9
  • 9
0

Please refer to the documentation. An excerpt:

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 Agents cannot be contributed to an already running JVM; the premain method is called before the main method, again as clearly documented:

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.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • my manifest is like this: Manifest-Version: 1.0 Class-Path: Premain-Class: ObjectSizeFetcher but it not work.. i use tomcat and my is a webapp – Andrea Catania Dec 08 '13 at 09:06
  • That cannot work. Agent JAR's can only be used for main entry points, not for web applications deployed into an already running application container. Also, you really should not place your class into the default package. – Marko Topolnik Dec 08 '13 at 09:18
  • hmmm, so the question is how can I get the size of an object of a webapp? – Andrea Catania Dec 08 '13 at 09:22