【如何查看java对象所占的内存大小】

我们为什么想要知道对象所占对内存的大小呢?

  (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 <Your main class>

  拿到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<Object, Object> visited = new IdentityHashMap<Object, Object>();

  Stack<Object> stack = new Stack<Object>();

  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<Object, Object> visited) {

  if (obj instanceof String) {

  // skip interned string

  if (obj == ((String) obj).intern()) {

  return true;

  }

  }

更多精彩教程请关注:win7系统下载

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值