All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sizeof.agent.SizeOfAgent Maven / Gradle / Ivy

Go to download

sizeofag is a Java Agent that allows you to determine the size of Java objects from within the JVM at runtime. This makes it very useful for developing Java frameworks that take memory constraints into account.

The newest version!
/*
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this program.  If not, see .
 */

package sizeof.agent;

import java.lang.instrument.Instrumentation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Stack;

/** 
 * Instrumentation agent used.
 * 

* This version merely outputs an error message on the commandline if the agent * is not present instead of throwing an exception. * * @author Maxim Zakharenkov * @author FracPete (fracpete at waikato dot ac dot nz) */ public class SizeOfAgent { static Instrumentation inst; static Boolean messageDisplayed; /** initializes agent */ public static void premain(String agentArgs, Instrumentation instP) { inst = instP; } /** * Returns object size without member sub-objects. * @param o object to get size of * @return object size, 0 is agent not present */ public static long sizeOf(Object o) { if(inst == null) { if (messageDisplayed == null) { messageDisplayed = true; System.err.println("Can not access instrumentation environment.\n" + "Please check if jar file containing SizeOfAgent class is \n" + "specified in the java's \"-javaagent\" command line argument."); } return 0; } return inst.getObjectSize(o); } /** * Calculates full size of object iterating over * its hierarchy graph. * @param obj object to calculate size of * @return object size */ public static long fullSizeOf(Object obj) { Map visited = new IdentityHashMap(); Stack stack = new Stack(); long result = internalSizeOf(obj, stack, visited); while (!stack.isEmpty()) { result += internalSizeOf(stack.pop(), stack, visited); } visited.clear(); return result; } private static boolean skipObject(Object obj, Map visited) { if (obj instanceof String) { // skip interned string if (obj == ((String) obj).intern()) { return true; } } return (obj == null) // skip visited object || visited.containsKey(obj); } private static long internalSizeOf(Object obj, Stack stack, Map visited) { if (skipObject(obj, visited)){ return 0; } visited.put(obj, null); long result = 0; // get size of object + primitive variables + member pointers result += SizeOfAgent.sizeOf(obj); // process all array elements Class clazz = obj.getClass(); if (clazz.isArray()) { if(clazz.getName().length() != 2) {// skip primitive type array int length = Array.getLength(obj); for (int i = 0; i < length; i++) { stack.add(Array.get(obj, i)); } } return result; } // process all fields of the object while (clazz != null) { Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (!Modifier.isStatic(fields[i].getModifiers())) { if (fields[i].getType().isPrimitive()) { continue; // skip primitive fields } else { fields[i].setAccessible(true); try { // objects to be estimated are put to stack Object objectToAdd = fields[i].get(obj); if (objectToAdd != null) { stack.add(objectToAdd); } } catch (IllegalAccessException ex) { assert false; } } } } clazz = clazz.getSuperclass(); } return result; } }