`
duankesong
  • 浏览: 12435 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

如何计算java对象的大小

阅读更多
是不是经常通过jvisualvm.exe来观察堆对象占用内存的变化?是不是在想oracle公司为啥不提供计算java对象大小的方法呢?
在企业开发中,前后台传递数据,如果数据比较大,进行持久化传递将会造成对象无法被虚拟机回收,进而导致内存泄漏,但一般是由于对象不较大引起的,因此需要对这些对象进行处理。google查询了一些资料,研究和整理如下:

1、利用序列化方法,这个经测试时比较接近的;
2、根据对象的大小进行估值;
3、使用虚拟机提供的函数,动态的,有时准确,有时不准确;
4、通过反射获取对象的大小,理论比较好,但没实现;
5、通过代理的方法来得到

下边主要说下序列化和虚拟机函数的方法。
序列化时通常把一个对象序列化到一个字节buffer里,那么就可以获得这个buffer的字节数。今天,在工作中,突软想到这样做太浪费空间,看了Java的ObjectOutputStream这个类的源码,发现也可以如下做,只计数,不产生字节转移,那么就不会耗费内存空间了。

  public final class SizeCalculator {

  public static int calcSize(java.io.Serializable o) {

  int ret = 0;

  class DumbOutputStream extends OutputStream {

  int count = 0;

  public void write(int b) throws IOException {

  count++; // 只计数,不产生字节转移

  }

  }

  DumbOutputStream buf = new DumbOutputStream();

  ObjectOutputStream os = null;

  try {

  os = new ObjectOutputStream(buf);

  os.writeObject(o);

  ret = buf.count;

  } catch (IOException e) {

  // No need handle this exception

  e.printStackTrace();

  ret = -1;

  } finally {

  try {

  os.close();

  } catch (Exception e) {

  }

  }

  return ret;

  }

  public static void main(String[] args){

  System.err.println(calcSize(1));

  }

  }
原文链接:http://www.linuxidc.com/Linux/2010-01/24222.htm

2、通过获取new对象前和后 Runtime.getRuntime().totalMemory( )计算它们的差值,还是有参考价值的,至于有的说先让虚拟机回收,这个不可行,因为虚拟机执行回收是自动的,并不能直接调用虚拟机进行对象回收的。  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics