奇怪的内存使用

Strange memory usage

在创建体素游戏的过程中,我正在为基本的块系统做一些性能测试。

一个块由 y 轴上的 16 个图块组成。 tile 是 material 个 ID 的 Hashmap。 key是一个byte,material id是一个short。

根据我的计算,一个块应该是 12KB + 一点点(假设是 16KB)。 16*16*16*3。 3 是一个字节和一个短字节(3 个字节)。

我基本上不明白的是我的应用程序使用了比预期多得多的内存。实际上每个块大约 256KB。它使用大约 2GB 运行ning 8192 个块。请注意,这是块存储性能测试,因此不是整个游戏。

另一件奇怪的事情是,每次我 运行 它的内存使用量从 1.9GB 到 2.2GB 不等。代码中没有随机化器,所以它应该始终是相同数量的变量、数组、元素等。

这是我的代码:

public class ChunkTest {

    public static void main(String[] args) {

        List <Chunk> chunks = new ArrayList <Chunk>();


        long time = System.currentTimeMillis();

        for(int i = 0; i<8192; i++) {
            chunks.add(new Chunk());
        }

        long time2 = System.currentTimeMillis();

        System.out.println(time2-time);

        System.out.println("Done");

        //System.out.println(chunk.getBlock((byte)0, (byte)0, (byte)0));

        while(1==1) {
            //Just to keep it running to view memory usage
        }


    }

}

还有一个class

public class Chunk {
    int x;
    int y;
    int z;

    boolean solidUp;
    boolean solidDown;
    boolean solidNorth;
    boolean solidSouth;
    boolean solidWest;
    boolean solidEast;

    private HashMap<Byte, HashMap<Byte, Short>> tiles = new HashMap<Byte, HashMap<Byte, Short>>();

    public Chunk() {
        HashMap<Byte, Short> tile;

        //Create 16 tiles
        for(byte i = 0; i<16;i++) {
            //System.out.println(i);
            tile = new HashMap<Byte, Short>();

            //Create 16 by 16 blocks (1 is the default id)
            for(short e = 0; e<256;e++) {
                //System.out.println(e);
                tile.put((byte) e, (short) 1);
            }

            tiles.put(i, tile);

        }
    }


    public short getBlock(byte x, byte y, byte z) {
        HashMap<Byte, Short> tile = tiles.get(y);

        short block = tile.get((byte)(x+(z*16)));

        return block;
    }

}

我正在使用 windows 任务管理器来监控内存使用情况。 这是一个非常不准确的监控工具吗,它是否有点猜测,这可以解释为什么它因实例而异。

是什么让每个块比它应该重 20 倍?

一个小问题,如果你知道:如果我知道我要查找的内容的索引,hashMap 或 ArrayList 更快吗?

A chunk is made of 16 tiles on the y axis. A tile is a Hashmap of material ids. The key is a byte, and the material id is a short.

According to my calculations a chunk should be 12KB + a little bit (Let's just say 16KB). 16*16*16*3. 3 is for a byte and a short(3 bytes).

太糟糕了。尽管您对 HashMap 的大小保密,但我看得出您过于乐观了。

一个Map.Entry是一个object。为其 header.

添加 4 或 8 个字节

它的密钥是 object,绝不是原始密钥。计数 8 个字节。

值相同。

A HashMap.Entry 存储散列(int,4 字节)和对 Entry next 的引用(4 或 8 字节)。 HashMap 维护一个对其条目的引用数组(每个元素 4 或 8 个字节),默认情况下最多保持 75% 满。

所以我们比您预期的要多得多。确切的值取决于你的 JVM,我上面的一些数字可能是错误的。不管怎样,你可能有 10 倍或更多。

我建议你 post 你编码为 CR with all the details needed for the size estimation. Consider using some primitive map 或者可能只是一个数组...