Java对象/原始大小

时间:2013-08-10 15:16:41

标签: java memory

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

  1. float(primitive)
  2. double(primitive)
  3. 布尔(原始)
  4. Float(Object)
  5. Double(Object)
  6. BigDecimal(Object)
  7. 布尔(对象)
  8. 对象指针
  9. 我的研究:

    我已经使用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)加上原语的大小。
    7. 布尔:

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

      我如何进行测试:

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

        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)));
            }
        
        }
        

        输出:

        test 0 - java.math.BigDecimal size:12144

        test 1 - java.math.BigDecimal size:12144

        test 2 - java.math.BigDecimal size:12144

        test 3 - java.math.BigDecimal size:12216

        test 4 - java.math.BigDecimal size:12208

        test 5 - java.math.BigDecimal size:12216

        test 6 - java.math.BigDecimal size:12224

        test 7 - com.george.test.info.TestBigDecimal size:12160

        test 8 - java.lang.Double size:296

        test 9 - java.lang.Double size:296

        test 10 - java.lang.Float size:288

        test 11 - java.lang.Float size:288

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

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

        test 14 - com.george.test.info.TestFloat size:16

        test 15 - java.lang.Boolean size:320

        test 16 - com.george.test.info.TestBool size:16

        test 17 - com.george.test.info.TestPacked2Bool size:16

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

        test 19 - com.george.test.info.TestPacked4Bool size:16

        test 20 - com.george.test.info.TestPacked5Bool size:24

        test 21 - com.george.test.info.TestPacked6Bool size:24

        test 22 - com.george.test.info.TestPacked7Bool size:24

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

        test 24 - com.george.test.info.TestPacked9Bool size:24

        test 25 - com.george.test.info.TestPacked10Bool size:24

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

        test 27 - com.george.test.info.TestPacked12Bool size:24

        test 28 - com.george.test.info.TestPacked13Bool size:32

        test 29 - com.george.test.info.TestPacked14Bool size:32

        test 30 - com.george.test.info.TestPacked15Bool size:32

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

        测试32 - com.george.test.info.TestPacked17Bool size:32

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

0 个答案:

没有答案