JAVA - 内存不足 - 体素世界生成

JAVA - Out Of Memory - Voxel World Generation

目前我有这个用于代码,我的游戏要么在生成(超过 GB)时使用大量内存,要么如果我将其设置得较低,它会给出

WORLD_SIZE_X & WORLD_SIZE_Z = 256;

WORLD_SIZE_Y = 128;

有谁知道我可以如何改进它以使其不使用那么多 RAM?

谢谢! :)

public void generate() {
    for(int xP = 0; xP < WORLD_SIZE_X; xP++) {
        for(int zP = 0; zP < WORLD_SIZE_Z; zP++) {
            for(int yP = 0; yP < WORLD_SIZE_Y; yP++) {

                try {
                    blocks[xP][yP][zP] = new BlockAir();

                    if(yP == 4) {
                        blocks[xP][yP][zP] = new BlockGrass();
                    }
                    if(yP < 4) {
                        blocks[xP][yP][zP] = new BlockDirt();
                    }
                    if(yP == 0) {
                        blocks[xP][yP][zP] = new BlockUnbreakable();
                    }
                } catch(Exception e) {}
            }


            //Tree Generation :D
            Random rX = new Random();
            Random rZ = new Random();
            if(rX.nextInt(WORLD_SIZE_X) < WORLD_SIZE_X / 6 && rZ.nextInt(WORLD_SIZE_Z) < WORLD_SIZE_Z / 6) {
                for(int j = 0; j < 5; j++) {
                    blocks[xP][5 + j][zP] = new BlockLog();
                }
            }
        }
    }
    generated = true;
}

延迟创建对象,直到您确实需要访问这些体素之一。您可以编写一个方法(我假设 Block 是所有 Block 类 的公共子类):

Block getBlockAt( int x, int y, int z )

使用类似于三重循环中的代码,加上使用哈希映射 Map<Integer,Block> 来存储随机内容,例如树:从 x、y 和 z 计算一个整数 (x*128 + y)*256 + z 并将其用作键。

此外,考虑到对于所有 "air"、"log"、"dirt" 块,您可能不需要单独的对象,除非必须在某个块处更改某些内容。在那之前,共享一个对象。

因为你只是给出一小段代码,我可以给你两个建议:

  1. 压缩对象大小。看起来很愚蠢但很容易做到。试想一下,您的记忆中有数千个对象。如果每个人都能压缩一半大小,就可以节省一半内存:).

  2. 需要的时候给数组赋值就行了。如果你真的需要一个分配的数组,有时它是行不通的。因此,只需尽可能少地为数组中的元素赋值。如果你能告诉我更多的代码,我可以帮助你更多。

您确定问题出在这个方法中吗?除非 Block 对象真的很大,否则 256*256*128 ~= 8M 对象应该不需要 1 GB ...

就是说,如果块不保持状态,使用枚举(甚至字节)会更节省内存,因为我们不需要为每个块单独的对象:

enum Block {
    air, grass, dirt, log, unbreakable;
}

Block[][][] map = ...