Java对象/原语大小

Java对象/原语大小,java,memory,Java,Memory,我正在努力弄清楚java中某些对象类型的大小。我的具体问题是,在64位机器上,以下对象/原语的大小是多少。我主要关心的是BigDecimal,但其他人也很想知道 浮动(基本) 双重(原语) 布尔(基元) 浮动(对象) 双重(对象) BigDecimal(对象) 布尔(对象) 对象指针 我的研究: 我已经使用SizeOf库()对不同大小的对象进行了一些实验测试,我对BigDecimal、Double、Float和Boolean的结果感到有些不安。它报告一个对象的大小超过12000字节——这似乎不可

我正在努力弄清楚java中某些对象类型的大小。我的具体问题是,在64位机器上,以下对象/原语的大小是多少。我主要关心的是BigDecimal,但其他人也很想知道

  • 浮动(基本)
  • 双重(原语)
  • 布尔(基元)
  • 浮动(对象)
  • 双重(对象)
  • BigDecimal(对象)
  • 布尔(对象)
  • 对象指针
  • 我的研究: 我已经使用SizeOf库()对不同大小的对象进行了一些实验测试,我对BigDecimal、Double、Float和Boolean的结果感到有些不安。它报告一个对象的大小超过12000字节——这似乎不可能是真的。它可能是真正的12k字节,或者库的大小不能正常工作。我将尝试使用jvisualvm确认这一点,稍后再发回

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

    观察:
  • sizeof.jar输出的数字以字节为单位
  • BigDecimal/Double/Float占用了大量内存,或者sizeof库存在问题
  • Sizeof似乎在报告对基本类型有意义的数字
  • 64位机器上的对象指针为8字节
  • TestEmpty是一个没有任何内容的类。我创建它作为参考。我不确定为什么报告为16字节,因为我认为应该只有8字节
  • 对于我添加来测量原语大小的测试类(TestDouble/TestFloat/etc),您需要从报告的数字中删除8个字节,因为SizeOf实际上报告的是对象指针(TestFloat)加上原语的大小
  • 布尔人: 布尔人似乎很有趣,值得更多的分析。看起来它们必须打包在一起,而且似乎每个都需要1个字节。我猜当java在64位系统上保留内存时,它只能分配8个字节或更多。布尔值实际上只需要存储1位,因此为单个布尔值分配8个字节将是一种可怕的浪费。因此,为了弥补我的猜测,java将把8个布尔值打包到8字节的连续内存中。我添加的每8个布尔值似乎会增加8个字节的内存。在8字节中存储64位会更节省空间,但我猜处理这些布尔值会更慢,因为它们必须解压缩并发送到处理器寄存器

    我是如何进行测试的:
  • 从中获取jar的大小
  • 将sizeof.jar添加到项目/类路径
  • 将sizeof的javaagent添加到服务器启动
  • sizeof仅适用于对象,因此要测试bool/float/double的大小,我创建的类只包含一个基本变量(TestBool、TestDoubld、TestFloat等)
  • 我创建了几个测试类来查看布尔值的大小。例如,TestPacked10Bool有10个布尔值
  • 在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)));
        }
    
    }
    
    publicstaticvoidtestobjectsize()
    {
    列表项=新建ArrayList();
    添加(新的BigDecimal(0));
    添加(新的BigDecimal(100000000));
    添加(新的BigDecimal(“1000000000”);
    添加(新的大十进制(“10000000000000000000”);
    添加(新的大十进制(“1000000000.0000000001”);
    添加(新的大十进制(“10000000000000000000.0000000001”);
    添加(新的大十进制(“10000000000000000000.000000000000000000000 1”);
    添加(新的TestBigDecimal());
    增加(新的双(0));
    增加(新的双倍(100000000));
    增加(新浮动(0));
    增加(新浮动(100000000));
    添加(新的TestDouble());
    items.add(newtestempty());
    添加(新的TestFloat());
    添加(新布尔值(true));
    添加(新的TestBool());
    添加(新的TestPacked2Bool());
    添加(新的TestPacked3Bool());
    添加(新的TestPacked4Bool());
    添加(新的TestPacked5Bool());
    添加(新的TestPacked6Bool());
    添加(新的TestPacked7Bool());
    添加(新的TestPacked8Bool());
    添加(新的TestPacked9Bool());
    添加(新的TestPacked10Bool());
    添加(新的TestPacked11Bool());
    添加(新的TestPacked12Bool());
    添加(新的TestPacked13Bool());
    添加(新的TestPacked14Bool());
    添加(新的TestPacked15Bool());
    添加(新的TestPacked16Bool());
    添加(新的TestPacked17Bool());
    添加(新的TestPacked64Bool());
    对于(int i=0;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大小:296

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

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

    测试12-com.george.test.info.test双码:24

    测试13-com.george.test.info.testy空尺寸: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.testpacked5池大小:24

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

    测试22-com.george.test.info.testpacked7工具大小:24

    测试23-com.george.test.info.testpacked8工具大小:24

    测试24-com.ge