可能重复:
In Java, what is the best way to determine the size of an object?
如果我们在类中创建实例变量和实例方法,那么如何找出为这个类的每个Object分配的总内存,如下所示,例如,我认为它是一些变量(a,b)
大小和方法区域大小(显示)。这是真的吗?那个写在课堂内的主要方法区域呢。
例如:
class A {
int a;
float b;
void display()
{
---
}
public static void main(String a[])
{
A obj=new A();
}
}
答案 0 :(得分:8)
简短的回答是除非你知道它有问题,否则你不需要知道。
更长的答案是它将使用对象标题的大约16个字节,每个字段使用4个字节(并将总数舍入为8字节边界),即24个字节。
局部变量,例如引用在堆栈上分配,通常不计算在内。
你通常不打扰大小的原因是1 MB的价值大约是你的2秒(比较内存的零售价和最低工资)这意味着你问这个问题的时间是值得的远远超过你可能保存的内存值(在这种情况下)
[4 GB模块的成本为18英镑,最低工资为8.50英镑,因此1 GB的价值约为0.5小时。 1 MB值约2秒。]
换句话说,如果一个简单的改变不能为你节省1 MB的内存,那么你可能会浪费你的时间。
这同样适用于移动设备,但程度较低(内存成本较高,如果部署到数千台设备,节省几百字节的总成本可能很重要)
这样做的结果是你写long
而不是int
或double
代替float
(他们都有一个额外的字符)所需的时间可以比它使用的额外内存价值数千倍。但是我仍然建议几乎总是使用double而不是float,而且通常是long而不是int,因为如果它保存了一个bug,它将弥补你必须输入的额外字符。
测量对象使用多少空间(或用于创建对象的内存量)的最简单方法是关闭TLAB -XX:-UseTLAB
并测量创建对象之前和之后的内存量使用Runtime.totalMemory - freeMemory。
但是,在我认为数据结构出现问题之前,我宁愿等到数据结构显示在像YourKit这样的探查器中(VisualVM是免费的)。
答案 1 :(得分:1)
您可以使用java.lang.instrumentation包: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/Instrumentation.html
编译并将此类放在JAR中:
import java.lang.instrument.Instrumentation;
public class ObjectSizeFetcher {
private static Instrumentation instrumentation;
public static void premain(String args, Instrumentation inst) {
instrumentation = inst;
}
public static long getObjectSize(Object o) {
return instrumentation.getObjectSize(o);
}
}
将以下内容添加到MANIFEST.MF
:
Premain-Class: ObjectSizeFetcher
使用getObjectSize()
:
public class C {
private int x;
private int y;
public static void main(String [] args) {
System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
}
}
使用java -javaagent:ObjectSizeFetcherAgent.jar C