为了账号安全,请及时绑定邮箱和手机立即绑定

内存中字节的大小-Java

/ 猿问

内存中字节的大小-Java

波斯汪 2019-11-08 11:16:54

我听过关于Java程序中一个字节占用的内存量的意见不一。


我知道您在一个Java字节中最多可以存储+127,并且文档说一个字节只有8位,但是在这里我被告知它实际上占用的内存量与int相同,因此仅一种有助于代码理解而不是效率的类型。


谁能解决这个问题,这将是实现特定的问题吗?


查看完整描述

3 回答

?
UYOU

好的,已经进行了很多讨论,而没有很多代码:)


这是一个快速基准。谈到这种事情时,通常会有一些警告-测试内存由于JITting等原因而有些奇怪,但是如果数量适当,它还是很有用的。它有两种类型,每种类型都有80个成员-LotsOfBytes具有80个字节,LotsOfInts具有80个int。我们构建了很多它们,确保它们没有被GC处理,并检查内存使用情况:


class LotsOfBytes

{

    byte a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;

    byte b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;

    byte c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;

    byte d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;

    byte e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;

}


class LotsOfInts

{

    int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;

    int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;

    int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;

    int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;

    int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;

}



public class Test

{

    private static final int SIZE = 1000000;


    public static void main(String[] args) throws Exception

    {        

        LotsOfBytes[] first = new LotsOfBytes[SIZE];

        LotsOfInts[] second = new LotsOfInts[SIZE];


        System.gc();

        long startMem = getMemory();


        for (int i=0; i < SIZE; i++)

        {

            first[i] = new LotsOfBytes();

        }


        System.gc();

        long endMem = getMemory();


        System.out.println ("Size for LotsOfBytes: " + (endMem-startMem));

        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));


        System.gc();

        startMem = getMemory();

        for (int i=0; i < SIZE; i++)

        {

            second[i] = new LotsOfInts();

        }

        System.gc();

        endMem = getMemory();


        System.out.println ("Size for LotsOfInts: " + (endMem-startMem));

        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));


        // Make sure nothing gets collected

        long total = 0;

        for (int i=0; i < SIZE; i++)

        {

            total += first[i].a0 + second[i].a0;

        }

        System.out.println(total);

    }


    private static long getMemory()

    {

        Runtime runtime = Runtime.getRuntime();

        return runtime.totalMemory() - runtime.freeMemory();

    }

}

在我的盒子上输出:


Size for LotsOfBytes: 88811688

Average size: 88.811688

Size for LotsOfInts: 327076360

Average size: 327.07636

0

因此,显然存在一些开销-从外观上看为8个字节,尽管不知何故LotsOfInts只有7个字节(如我所说,这里有些奇怪)-但问题是字节字段似乎被打包成LotsOfBytes这样, (除去开销后)仅占用LotsOfInts内存的四分之一。


查看完整回答
反对 回复 2019-11-08
?
元芳怎么了

是的,Java中的字节变量实际上是内存中的4个字节。但是,这不适用于数组。实际上,一个20字节的字节数组存储在内存中只有20字节。


这是因为Java字节码语言仅知道两种整数类型:ints和longs。因此,它必须内部处理所有数字,无论哪种类型,并且这些类型在内存中分别为4和8字节。


但是,Java知道具有每种整数格式的数组。因此,短数组的存储实际上是每个条目两个字节,对于字节数组每个条目一个字节。


我一直说“的存储”的原因是,数组也是Java中的一个对象,每个对象本身都需要多个字节的存储空间,而与实例变量或数组需要的数组存储空间无关。


查看完整回答
反对 回复 2019-11-08
?
临摹微笑

我使用http://code.google.com/p/memory-measurer/进行了测试, 请注意,我使用的是64位Oracle / Sun Java 6,未压缩任何引用等。


每个对象都占用一些空间,加上JVM需要知道该对象的地址,并且“地址”本身是8个字节。


使用基元,看起来基元被强制转换为64位以获得更好的性能(当然!):


byte: 16 bytes,

 int: 16 bytes,

long: 24 bytes.

使用数组:


byte[1]: 24 bytes

 int[1]: 24 bytes

long[1]: 24 bytes


byte[2]: 24 bytes

 int[2]: 24 bytes

long[2]: 32 bytes


byte[4]: 24 bytes

 int[4]: 32 bytes

long[4]: 48 bytes


byte[8]: 24 bytes => 8 bytes, "start" address, "end" address => 8 + 8 + 8 bytes

 int[8]: 48 bytes => 8 integers (4 bytes each), "start" address, "end" address => 8*4 + 8 + 8 bytes

long[8]: 80 bytes => 8 longs (8 bytes each), "start" address, "end" address => 8x8 + 8 + 8 bytes

现在猜猜...


    byte[8]: 24 bytes

 byte[1][8]: 48 bytes

   byte[64]: 80 bytes

 byte[8][8]: 240 bytes

PS Oracle Java 6,最新,最出色的64位1.6.0_37,MacOS X


查看完整回答
反对 回复 2019-11-08

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信