java - 奇怪的内存使用情况

标签 java performance memory ram

在创建体素游戏的过程中,我正在对基本 block 系统进行一些性能测试。

一个 block 由 y 轴上的 16 个图 block 组成。图 block 是 Material ID 的 HashMap 。 key是一个byte,material id是一个short。

根据我的计算,一个 block 应该是 12KB + 一点点(我们就说 16KB)。 16*16*16*3。 3 代表一个字节和一个短字节(3 个字节)。

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

另一个奇怪的事情是每次运行时内存使用量从 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 任务管理器来监视内存使用情况。 这是一个非常不准确的监控工具吗?它是否是一种猜测,这可以解释为什么它因实例而异。

是什么让每个 block 比应有的重 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 是一个对象。为其 header 添加 4 或 8 个字节。

它的键是一个对象,而不是基元。数8个字节。

值相同。

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

因此,我们提供的内容远远超出您的预期。确切的值取决于您的 JVM,我上面的一些数字可能是错误的。不管怎样,你的差距可能是 10 倍或更多。

我建议您将代码发布到 CR包含尺寸估算所需的所有详细信息。考虑使用一些primitive map或者也许只是一个数组...

关于java - 奇怪的内存使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30290621/

相关文章:

java - 从 json 中过滤唯一列表

java - 为什么我的 Android 应用程序中不断出现 java.net.ConnectException?

performance - Qt QMap 和 QList 速度

c - 这些 C "MAX"宏中哪个最好?

performance - 用于处理 future 事件的查找结构(基于时间)

java - 内存中的图像消耗的内存远多于其文件大小

java - 在 JNI 实现中创建静态全局变量不好吗?

java - 为什么我不能在 eclipse.ini 中将 -Xmx 设置为 1024m?

Android:无法使用下载管理器将从服务器下载的数据保存到内存

java - 如何使用 RxJava 执行有序合并?