首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >内存中字节的大小- Java

内存中字节的大小- Java
EN

Stack Overflow用户
提问于 2008-10-23 14:16:35
回答 8查看 70.2K关注 0票数 56

关于一个字节在java程序中占用的内存量,我听到过各种不同的意见。

我知道你可以在一个java字节中存储不超过+127的内容,documentation说一个字节只有8位,但是here我被告知它实际上占用了与int相同的内存量,因此只是一种有助于代码理解而不是效率的类型。

有人可以澄清这一点吗?这会是一个特定于实现的问题吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2008-10-23 14:57:27

好的,有很多讨论,但没有太多代码:)

这里有一个快速基准。当涉及到这类事情时,它有通常的警告-测试内存由于JITting等原因而有些奇怪,但对于适当的大数字,它无论如何都是有用的。它有两种类型,每种都有80个成员-- LotsOfBytes有80个字节,LotsOfInts有80个It。我们构建了大量的内存,确保它们没有被GC,并检查内存使用情况:

代码语言:javascript
复制
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();
    }
}

我盒子上的输出:

代码语言:javascript
复制
Size for LotsOfBytes: 88811688
Average size: 88.811688
Size for LotsOfInts: 327076360
Average size: 327.07636
0

因此,显然有一些开销-8字节,尽管不知何故只有7字节的LotsOfInts (?就像我说的,这里有一些奇怪的地方)--但关键是字节字段似乎被打包到了LotsOfBytes中,因此(在去掉开销后)它只需要LotsOfInts的四分之一的内存。

票数 67
EN

Stack Overflow用户

发布于 2008-10-23 14:35:20

是的,Java中的byte变量实际上是内存中的4个字节。然而,这并不适用于数组。20字节的字节数组的存储实际上在存储器中仅为20字节。

这是因为Java字节码语言只知道两种整数类型:int和long。因此,它必须在内部将所有数字处理为任一类型,并且这些类型在内存中是4字节和8字节。

然而,Java知道每个整数格式的数组。因此,短数组的存储实际上是每个条目两个字节,字节数组的每个条目一个字节。

我之所以一直说“的存储”,是因为在Java中,数组也是一个对象,每个对象本身都需要多个字节的存储空间,而不管实例变量或数组所需的存储空间是多少。

票数 20
EN

Stack Overflow用户

发布于 2008-10-23 14:21:09

Java从来不是特定于实现或平台的(至少就primitive type sizes而言)。无论你在什么平台上,它们的基本类型总是保持不变。这不同于(也被认为是)C和C++的改进,后者的一些原语类型是特定于平台的。

由于底层操作系统一次寻址四个字节(在64位系统中为八个字节)的速度更快,JVM可能会分配更多的字节来存储一个原始字节,但是您仍然只能在其中存储从-128到127的值。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/229886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档