怎么计算java对象的大小
如何计算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( )计算它们的差值,还是有参考价值的,至于有的说先让虚拟机回收,这个不可行,因为虚拟机执行回收是自动的,并不能直接调用虚拟机进行对象回收的。
是不是经常通过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( )计算它们的差值,还是有参考价值的,至于有的说先让虚拟机回收,这个不可行,因为虚拟机执行回收是自动的,并不能直接调用虚拟机进行对象回收的。