当前位置:  开发笔记 > 编程语言 > 正文

内存中字节的大小 - Java

如何解决《内存中字节的大小-Java》经验,为你挑选了5个好方法。

我听说过一个字节在java程序中占用的内存量的混合意见.

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

任何人都可以清除这一点,这是一个特定于实现的问题吗?



1> Jon Skeet..:

好的,有很多讨论而不是很多代码:)

这是一个快速的基准.当涉及到这种事情时,它有正常的警告 - 由于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的四分之一.


这取决于JVM.Sun与8个字节边界对齐
@kohlerm:那是Sun JVM.

2> Mecki..:

是的,一个字节变量实际上是内存中的4个字节.然而,对于数组而言,这并不适用.事实上,20字节的字节数组实际上只有20个字节.这是因为Java字节码语言只知道int和long作为数字类型(所以它必须处理所有数字作为两种类型,4字节或8字节),但它知道具有每个可能的数字大小的数组(所以短数组在事实上,每个条目两个字节和字节数组实际上每个条目一个字节).



3> Bill the Liz..:

Java永远不是实现或平台特定的(至少就原始类型大小而言).无论您使用什么平台,它们始终保证原始类型保持不变.这与C和C++不同(并且被认为是一种改进),其中一些原始类型是特定于平台的.

由于底层操作系统一次更快地处理四个(或八个,64位系统)字节,因此JVM可以分配更多字节来存储一个原始字节,但是你仍然只能存储-128到-128的值. 127在其中.



4> izb..:

一个显而易见的练习是在一些代码上运行javap,这些代码用字节和整数做简单的事情.您将看到字节码,它们希望int参数在字节上运行,并且字节码被插入以便从一个字节到另一个字符串.

请注意,字节数组不会存储为4字节值的数组,因此1024字节的字节数组将使用1k的内存(忽略任何开销).



5> Fuad Efendi..:

我使用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.

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有