【发布时间】:2019-03-20 16:41:38
【问题描述】:
我正在制作一个 Minecraft 克隆,我有一个名为 chunks 的 Map<Vector3i, Chunk> 存储所有加载的块。每一帧,这个循环都会运行:
for(Vector3i v:chunksToUnrender){
...
CompletableFuture.runAsync(() -> {
try {
chunks.get(v).toFile(new File(String.format("res-server/regions/%s.%s.%s.mcr", v.x, v.y, v.z)));
synchronized (chunksStateGuard) {
chunks.remove(v);
}
} catch(IOException e) {
e.printStackTrace();
System.err.println("Unable to save chunk " + Utils.format3i(v));
}
});
}
这里的目标是异步卸载块。 Chunk.toFile(File)的内容是:
public void toFile(File file) throws IOException {
FileOutputStream fos = new FileOutputStream(file);
fos.write(SerializationUtils.serialize(this));
fos.flush();
fos.close();
}
然而,尽管使用了CompletableFuture,当一个块被卸载时,游戏会在短时间内触发帧率,因为它会序列化并卸载该块。有什么办法可以避免在后台任务工作时中断主线程?
【问题讨论】:
-
文件 IO 成本很高,您是否考虑过将常用内容序列化到内存缓存(例如 ehCache 或 Terracota)或从内存缓存中序列化?
-
@RahulR。序列化的重点是减少内存消耗。最初所有的块总是存储在内存中,但是在大约 1m 的游戏过程中,我们会得到延迟峰值和 OutOfMemoryErrors。
-
@RahulR。我不明白你的意思。如果您的建议可以解决问题,请发布答案。
标签: java performance asynchronous serialization completable-future