5

可能重复:
在 Java 中,确定对象大小的最佳方法是什么?

如果我们在一个类中创建实例变量和实例方法,那么如何找出为该类的每个对象分配的总内存,如下所示,例如,我认为它是一些变量(a,b)大小和方法区域大小(显示)。是真的吗?写在类中的主要方法区域怎么样。

例如:

class A {  
    int a;
    float b;
    void display()
    {  
       ---
    }

    public static void main(String a[])
    { 
        A obj=new A();
    }
}
4

2 回答 2

8

简短的回答是你不需要知道,除非你知道这是一个问题。

更长的答案是它将使用大约 16 个字节的对象标头,每个字段 4 个字节(并将总数四舍五入到 8 个字节的边界),即 24 个字节。

局部变量,例如引用是在堆栈上分配的,通​​常不计算在内。

您通常不关心大小的原因是 1 MB 值得您花费大约 2 秒的时间(将内存的零售价与最低工资进行比较)这意味着您提出问题所花费的时间远远超过您可能保存的内存值(在这种情况下)

[一个 4 GB 模块的成本为 18 英镑,最低工资为 8.50 英镑,因此 1 GB 大约值 0.5 小时。1 MB 大约值 2 秒。]

换句话说,如果一个简单的更改不能为您节省 1 MB 的内存,您可以更好地使用它,那么您可能会浪费您的时间。

这同样适用于移动设备,但程度较小(内存成本更高,如果将其部署到数千台设备,节省几百字节的总成本可能很重要)

long这样做的结果是,代替intdouble代替(它们都有一个额外的字符)所花费float的时间可能比它使用的额外内存价值高出数千倍。但是,我仍然建议几乎总是使用 double 而不是 float,并且通常使用 long 而不是 int,因为如果它节省了一个错误,它将弥补您必须输入的额外字符。


测量对象使用了多少空间(或创建对象使用了多少内存)的最简单方法是关闭 TLAB-XX:-UseTLAB并使用 Runtime.totalMemory - freeMemory 测量创建对象前后的内存量。

但是,我更愿意等到数据结构出现在像 YourKit(VisualVM 是免费的)这样的分析器中,然后我才认为这是一个问题。

于 2012-05-05T07:55:51.780 回答
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

于 2012-05-05T07:58:35.317 回答