3

我试图弄清楚java中某些对象类型的大小。我的具体问题是 64 位机器上以下对象/基元的大小是多少。我主要关心 BigDecimal - 但其他人也很高兴知道。

  1. 浮动(原始)
  2. 双(原始)
  3. 布尔值(原始)
  4. 浮动(对象)
  5. 双(对象)
  6. BigDecimal(对象)
  7. 布尔值(对象)
  8. 对象指针

我的研究:

我已经使用 SizeOf 库 ( http://sizeof.sourceforge.net/ )对不同的对象大小进行了一些实验性测试,我对 BigDecimal、Double、Float、Boolean 看到的内容有些不安。它报告一个对象的大小超过 12,000 字节 - 这似乎不可能是真的。它要么是真正的 12k 字节,要么是 SizeOf 库无法正常工作。我将尝试使用 jvisualvm 确认这一点,稍后再发回。

我确实在 BigDecimal 的另一个线程中找到了另一个帖子,但我不确定答案是否正确:Java BigDecimal memory usage?

观察:

  1. sizeof.jar 输出的数字以字节为单位。
  2. BigDecimal/Double/Float 会占用大量内存,或者 sizeof 库存在问题。
  3. Sizeof 似乎正在报告对原始类型有意义的数字
  4. 64 位机器上的对象指针是 8 个字节
  5. TestEmpty 是一个没有任何内容的类。我创建它以供参考。不知道为什么它报告为 16 个字节,因为我认为它应该只有 8 个。
  6. 对于我添加的用于测量基元大小的测试类(TestDouble/TestFloat/etc),您需要从报告的数字中删除 8 个字节,因为 SizeOf 实际上是在报告对象指针(TestFloat)加上基元的大小。

布尔值:

布尔值似乎很有趣,值得更多分析。看起来它们必须打包在一起,并且似乎每个都需要 1 个字节。我猜当 java 在 64 位系统上保留内存时,它只能分配 8 个字节或更多。布尔值实际上应该只需要存储 1 位,因此为单个布尔值分配 8 个字节将是一种可怕的浪费。所以为了补偿我猜测java会将8个布尔值打包到8个字节的连续内存中。我添加的每 8 个布尔值似乎会使内存增加 8 个字节。在 8 个字节中存储 64 位会更节省空间,但我猜测处理这些布尔值会更慢,因为它们必须被解包并发送到处理器寄存器。

我是如何进行测试的:

  1. http://sizeof.sourceforge.net/获取 sizeof jar
  2. 将 sizeof.jar 添加到项目/类路径
  3. 将 sizeof 的 javaagent 添加到服务器启动
  4. sizeof 仅适用于对象,因此为了测试 bool/float/doubles 的大小,我创建了只包含单个原始变量(TestBool、TestDoubld、TestFloat 等)的类
  5. 我创建了几个测试类来查看布尔值的大小。例如 TestPacked10Bool 有 10 个布尔值。
  6. 在 64 位系统上运行。

这是我的测试代码:

public static void testObjectSizes()
{
    List <Object> items = new ArrayList<Object>();

    items.add(new BigDecimal(0));
    items.add(new BigDecimal(1000000000));
    items.add(new BigDecimal("1000000000"));
    items.add(new BigDecimal("1000000000000000000000"));
    items.add(new BigDecimal("1000000000.0000000001"));
    items.add(new BigDecimal("1000000000000000000000.0000000001"));
    items.add(new BigDecimal("1000000000000000000000.0000000000000000000001"));
    items.add(new TestBigDecimal());
    items.add(new Double(0));
    items.add(new Double(1000000000));
    items.add(new Float(0));
    items.add(new Float(1000000000));
    items.add(new TestDouble());
    items.add(new TestEmpty());
    items.add(new TestFloat());
    items.add(new Boolean(true));
    items.add(new TestBool());
    items.add(new TestPacked2Bool());
    items.add(new TestPacked3Bool());
    items.add(new TestPacked4Bool());
    items.add(new TestPacked5Bool());
    items.add(new TestPacked6Bool());
    items.add(new TestPacked7Bool());
    items.add(new TestPacked8Bool());
    items.add(new TestPacked9Bool());
    items.add(new TestPacked10Bool());
    items.add(new TestPacked11Bool());
    items.add(new TestPacked12Bool());
    items.add(new TestPacked13Bool());
    items.add(new TestPacked14Bool());
    items.add(new TestPacked15Bool());
    items.add(new TestPacked16Bool());
    items.add(new TestPacked17Bool());
    items.add(new TestPacked64Bool());

    for (int i = 0 ;i < items.size(); i++)
    {
        System.out.println("test " + i +  " - " +items.get(i).getClass().getName() + " size:" + SizeOf.deepSizeOf(items.get(i)));
    }

}

输出:

测试 0 - java.math.BigDecimal 大小:12144

测试 1 - java.math.BigDecimal 大小:12144

测试 2 - java.math.BigDecimal 大小:12144

测试 3 - java.math.BigDecimal 大小:12216

测试 4 - java.math.BigDecimal 大小:12208

测试 5 - java.math.BigDecimal 大小:12216

测试 6 - java.math.BigDecimal 大小:12224

测试 7 - com.george.test.info.TestBigDecimal 大小:12160

测试 8 - java.lang.Double 大小:296

测试 9 - java.lang.Double size:296

测试 10 - java.lang.Float 大小:288

测试 11 - java.lang.Float 大小:288

测试 12 - com.george.test.info.TestDouble 大小:24

测试 13 - com.george.test.info.TestEmpty 大小:16

测试 14 - com.george.test.info.TestFloat 大小:16

测试 15 - java.lang.Boolean 大小:320

测试 16 - com.george.test.info.TestBool 大小:16

测试 17 - com.george.test.info.TestPacked2Bool 大小:16

测试 18 - com.george.test.info.TestPacked3Bool 大小:16

测试 19 - com.george.test.info.TestPacked4Bool 大小:16

测试 20 - com.george.test.info.TestPacked5Bool 大小:24

测试 21 - com.george.test.info.TestPacked6Bool 大小:24

测试 22 - com.george.test.info.TestPacked7Bool 大小:24

测试 23 - com.george.test.info.TestPacked8Bool 大小:24

测试 24 - com.george.test.info.TestPacked9Bool 大小:24

测试 25 - com.george.test.info.TestPacked10Bool 大小:24

测试 26 - com.george.test.info.TestPacked11Bool 大小:24

测试 27 - com.george.test.info.TestPacked12Bool 大小:24

测试 28 - com.george.test.info.TestPacked13Bool 大小:32

测试 29 - com.george.test.info.TestPacked14Bool 大小:32

测试 30 - com.george.test.info.TestPacked15Bool 大小:32

测试 31 - com.george.test.info.TestPacked16Bool 大小:32

测试 32 - com.george.test.info.TestPacked17Bool 大小:32

测试 33 - com.george.test.info.TestPacked64Bool 大小:80

4

0 回答 0