奇怪的内存使用
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 或者可能只是一个数组...
在创建体素游戏的过程中,我正在为基本的块系统做一些性能测试。
一个块由 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.
它的密钥是 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 或者可能只是一个数组...