java检测返回的大小单位

时间:2014-12-05 13:39:48

标签: java instrumentation

我使用以下java项目来确定对象的大小 http://sizeof.sourceforge.net/

public class DataClass /*implements Serializable*/{

    // private static final long serialVersionUID = 5199373516861766638L;
    String name = "GUNJ";
    String lastName= "";

    // int age = 148888890;

    @Override
    public String toString() {
        return "DataClass{" +
                "Name='" + name + '\'' +
                ", Last Name='" + lastName + '\'' +
                ", Age=" +
                '}';

    }

    public static void main(String[] args) {

        // SizeOf.skipStaticField(true);
        // SizeOf.skipFinalField(true);
        // SizeOf.skipFlyweightObject(true);

        System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new DataClass()))); //this will print the object size in bytes
    }

}

我得到如下结果 144Kb,64Kb,72Kb

  1. ''这里代表位或字节?
  2. 为什么输出不会随着我改变上述情况下的字符数而改变?有时它会增加而有时则不会增加。
  3. 似乎正在使用Java检测代码

    似乎正在使用以下包:java.lang.instrument.Instrumentation

    但不确定包的API是以位还是字节返回对象大小。

3 个答案:

答案 0 :(得分:1)

这个工具似乎有点过时了。作为替代方案,我可以建议优秀的JOL,现在已经在OpenJDK下发布了。 它甚至比sizeOf更好,并支持许多很酷的功能。 另请查看演示此工具使用情况的Shipilev's blog post

答案 1 :(得分:0)

您指出的链接指出:

Use the humanReadable() method to get the object size in byte, kilo or mega (if you need giga your in trouble guy!):

所以它似乎没有位。

对于你的第二个问题,我没有答案。我猜String使用的缓冲区大小大于字符串的大小,所以你可以在缓冲区大小增加之前添加几个字符。

答案 2 :(得分:0)

对于这样的小物件,我不相信你会得到像“144Kb,64Kb,72Kb”这样的结果。你很可能得到144.0b64.0b72.0b

page you have linked已经说过没有任何疑惑的余地:

  

的System.out.println(SizeOf.deepSizeOf()); //这将打印以字节为单位的对象大小

如果您对SizeOf.humanReadable的含义持怀疑态度,可以省略其调用并直接打印SizeOf.deepSizeOf的结果。


由于skipStaticFieldskipFinalFieldskipFlyweightObject是三个标志,因此允许八种组合,但是您只发布了三个结果而没有告诉您使用的组合,因此很难解释结果。特别是,由于String的实现在Java版本之间发生了变化,因此您没有指定使用过的Java版本。

如果指定了skipFlyweightObject,则源代码中的文字String之类的实习String不计算在内。如果未指定skipFinalField,则会计算String的平面对象存储,但忽略其char[]内容,因为它使用final字段引用。如果计算了所有char,则必须考虑大多数实现都有一个对象大小填充,可以在报告对象大小时进行计算。

似乎在Oracle的JVM中,每个对象的对象大小都是八个字节的倍数。因此,在UTF-16数组的对象大小增加到八个字节的下一个倍数之前,您最多可以添加四个char个字符。


您可以使用SizeOf.turnOnDebug();来了解如何计算对象大小。但是你应该始终记住,这样的累积大小可能包括在不同对象图之间共享的对象,因此加起来比实际使用的堆存储大得多。

还要考虑SizeOf类后端documentation of Instrumentation.getObjectSize的内容:

  

返回指定对象占用的存储量的特定于实现的近似值。 结果可能包括对象的部分或全部开销,因此可用于实现中的比较,但不适用于实现之间。在单次调用JVM期间,估计值可能会发生变化。(由我强调)