为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

查看java对象所占的内存大小的方法

2017-03-21 9页 doc 8KB 13阅读

用户头像

is_281650

暂无简介

举报
查看java对象所占的内存大小的方法查看java对象所占的内存大小的方法   做一些cache的时候,我们不可能把数据库的所有的数据都缓存到内存里面,我们要估计缓存的大小。那么如何查看对象所占的内存大小呢?本文为大家介绍一下方法,希望可以为您提供帮助!更多内容请关注网!   (1)做一些cache的时候,我们不可能把数据库的所有的数据都缓存到内存里面,我们要估计缓存的大小。   (2)内存泄露的时候,我们可以查看某些对象的大小来定位问题,当然还有其他的更有效的方式,比如使用MAT分析dump文件   (3)根据jvm的堆内存设置,我们可以知道最多可以创建多少个对...
查看java对象所占的内存大小的方法
查看java对象所占的内存大小的方法   做一些cache的时候,我们不可能把数据库的所有的数据都缓存到内存里面,我们要估计缓存的大小。那么如何查看对象所占的内存大小呢?本文为大家介绍一下方法,希望可以为您提供帮助!更多内容请关注网!   (1)做一些cache的时候,我们不可能把数据库的所有的数据都缓存到内存里面,我们要估计缓存的大小。   (2)内存泄露的时候,我们可以查看某些对象的大小来定位问题,当然还有其他的更有效的方式,比如使用MAT分析dump文件   (3)根据jvm的堆内存设置,我们可以知道最多可以创建多少个对象。   从jdk5开始,提供了Instrumentation API,它有一个叫做getObjectSize()的方法,但是,这个方法存在两个问题:   (1)不可以直接使用。必须要实现一个Instrumentation Agent,还得放到jar包里面。   (2)它只能返回单个对象的大小,不能返回内部包含的子对象的大小。   关于第一个问题,很好解决,在任何一个类里面声明一个"premain"方法,就可以把这个类做成是一个agent:   public class SizeOfAgent {   static Instrumentation inst;   /** initializes agent */   public static void premain(String agentArgs, Instrumentation instP) {   inst = instP;   }   }   jvm在启动的时候会调用premain()方法,同时会传递Instrumentation这个对象实例,要告诉jvm Instrumentation agent所在的类,需要把这个类打到jar包里面,   然后在manifest.mf这个文件设置一些属性:   Premain-Class: sizeof.agent.SizeOfAgent   Boot-Class-Path:   Can-Redefine-Classes: false   java应用在启动的时候,指定-javaagent参数:   java -javaagent:sizeofag.jar   拿到Instrumentation这个实例以后,就可以调用sizeOf()方法了:   public class SizeOfAgent {   static Instrumentation inst;   // ...   public static long sizeOf(Object o) {   return inst.getObjectSize(o);   }   }   然后可以使用反射来获取子对象的大小。   完整的代码如下:   package com.bj58.test;   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;   public class SizeOfAgent {   static Instrumentation inst;   /** 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   */   public static long sizeOf(Object o) {   if (inst == null) {   throw new IllegalStateException(   "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 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;   }   }   然后我们可以做一个测试:   public class Test {   static class Person{   private int id;   private String name;   private String address;   public Person(int id, String name, String address) {   this.id = id;   this.name = name;   this.address = address;   }   }   public static void main(String[] args) throws Exception {   Person p = new Person(12, "xujsh","bj");   long size = SizeOfAgent.fullSizeOf(p);   System.out.println(size);   }   }   切换到命令行:   D:\workspace\objsize\src>java -version   java version "1.6.0_22"   Java(TM) SE Runtime Environment (build 1.6.0_22-b04)   Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)   D:\workspace\objsize\src>javac com/bj58/test/*.java   D:\workspace\objsize\src>jar -cvfm size.jar MANIFEST.MF com/bj58/test/*   标明(manifest)   增加:com/bj58/test/SizeOfAgent.class(读入= 3119) (写出= 1698)(压缩了 45%)   增加:com/bj58/test/SizeOfAgent.java(读入= 3147) (写出= 1204)(压缩了 61%)   增加:com/bj58/test/Test$Person.class(读入= 442) (写出= 305)(压缩了 30%)   增加:com/bj58/test/Test.class(读入= 692) (写出= 441)(压缩了 36%)   增加:com/bj58/test/Test.java(读入= 509) (写出= 290)(压缩了 43%)   D:\workspace\objsize\src>java -javaagent:size.jar com.bj58.test.Test   24   MANIFEST.MF:   Manifest-Version: 1.0   Main-Class: com.bj58.test.Test   Premain-Class: com.bj58.test.SizeOfAgent   Boot-Class-Path:   Can-Redefine-Classes: false   【注意】MANIFEST.MF文件的格式比较严格,每一行要满足:key:空格value回车   \   如何在web应用程序里面使用呢?   以我的tomcat为例,   (1)把size.jar上传tomcat的lib目录下面   (2)修改catalina.sh:   添加一行:   JAVA_OPTS="$JAVA_OPTS -javaagent:$CATALINA_HOME/lib/size.jar"  //这一行是新添加的   if [ -z "$LOGGING_MANAGER" ]; then   JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"   else   JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER"   fi   (3)在应用里面添加一个controler:   @Path(value = "/api/size")   @GET   public ActionResult size() {   Map> map = ApiUtils.getHotindexBaidu();   long size = SizeOfAgent.fullSizeOf(map);   return new ApiActionResult("size:"+size);   }
/
本文档为【查看java对象所占的内存大小的方法】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索