哦,亲爱的,垃圾收集器。 我遇到了java outOfMemory错误。
堆栈跟踪:
[09:44:10] 2014-01-22 09:44:10 [INFO] [STDERR] java.lang.OutOfMemoryError: Java heap space
[09:44:11] 2014-01-22 09:44:10 [INFO] [STDERR] at net.minecraft.util.AABBPool.getAABB(AABBPool.java:50)
[09:44:11] 2014-01-22 09:44:11 [INFO] [STDERR] at net.minecraft.block.Block.getCollisionBoundingBoxFromPool(Block.java:602)
[09:44:12] 2014-01-22 09:44:12 [INFO] [STDERR] at net.minecraft.block.Block.addCollisionBoxesToList(Block.java:568)
[09:44:14] 2014-01-22 09:44:14 [INFO] [STDERR] at net.minecraft.world.World.getCollidingBoundingBoxes(World.java:1684)
[09:44:15] 2014-01-22 09:44:14 [INFO] [STDERR] at net.minecraft.entity.player.EntityPlayerMP.<init>(EntityPlayerMP.java:187)
[09:44:17] 2014-01-22 09:44:15 [INFO] [STDERR] at net.minecraft.server.management.ServerConfigurationManager.createPlayerForUser(ServerConfigurationManager.java:389)
[09:44:18] 2014-01-22 09:44:17 [INFO] [STDERR] at net.minecraft.server.integrated.IntegratedServerListenThread.networkTick(IntegratedServerListenThread.java:91)
[09:44:19] 2014-01-22 09:44:18 [INFO] [STDERR] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:691)
[09:44:20] 2014-01-22 09:44:19 [INFO] [STDERR] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:587)
[09:44:22] 2014-01-22 09:44:20 [INFO] [STDERR] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:129)
[09:44:23] 2014-01-22 09:44:22 [INFO] [STDERR] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:484)
[09:44:24] 2014-01-22 09:44:23 [INFO] [STDERR] at net.minecraft.server.ThreadMinecraftServer.run(ThreadMinecraftServer.java:16)
[09:44:33] 2014-01-22 09:44:24 [SEVERE] [Minecraft-Server] Encountered an unexpected exception OutOfMemoryError
[09:44:33] java.lang.OutOfMemoryError: Java heap space
[09:44:33] at net.minecraft.util.AABBPool.getAABB(AABBPool.java:50)
[09:44:33] at net.minecraft.block.Block.getCollisionBoundingBoxFromPool(Block.java:602)
[09:44:33] at net.minecraft.block.Block.addCollisionBoxesToList(Block.java:568)
[09:44:33] at net.minecraft.world.World.getCollidingBoundingBoxes(World.java:1684)
[09:44:33] at net.minecraft.entity.player.EntityPlayerMP.<init>(EntityPlayerMP.java:187)
[09:44:33] at net.minecraft.server.management.ServerConfigurationManager.createPlayerForUser(ServerConfigurationManager.java:389)
[09:44:33] at net.minecraft.server.integrated.IntegratedServerListenThread.networkTick(IntegratedServerListenThread.java:91)
[09:44:33] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:691)
[09:44:33] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:587)
[09:44:33] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:129)
[09:44:33] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:484)
[09:44:33] at net.minecraft.server.ThreadMinecraftServer.run(ThreadMinecraftServer.java:16)
使用Eclipse Memory Analyzer收集的信息:
The thread net.minecraft.server.ThreadMinecraftServer @ 0xbdf43f30 Server thread keeps local variables with total size 935,606,320 (87.86%) bytes.
The memory is accumulated in one instance of "java.lang.Object[]" loaded by "<system class loader>".
Keywords
java.lang.Object[]
Shortest Paths To the Accumulation Point
Class Name Shallow Heap Retained Heap
|-> java.lang.Object[17176655] @ 0xee3868b8 68,706,640 935,599,248
\-> elementData java.util.ArrayList @ 0xc22cbc80 24 935,599,272
-\-> listAABB net.minecraft.util.AABBPool @ 0xbff74570 40 935,599,312
--\-> value java.lang.ThreadLocal$ThreadLocalMap$Entry @ 0xc1844bc0 32 935,599,344
---\-> [58] java.lang.ThreadLocal$ThreadLocalMap$Entry[64] @ 0xbe0330b0 272 935,605,248
----\-> table java.lang.ThreadLocal$ThreadLocalMap @ 0xbe036680 24 935,605,272
-----\-> threadLocals net.minecraft.server.ThreadMinecraftServer @ 0xbdf43f30 Server thread Thread 120 935,606,320
Accumulated Object by class:
net.minecraft.util.AxisAlignedBB | Number of Objects: 13,545,197 | Used Heap Size: 866,892,608 | Retained Heap Size: 866,892,608
作为outOfMemory错误源的函数是:
private static int getNextEmptyId()
{
int temp = 0;
for(; temp < blocksList.length; temp++)
{
if(blocksList[temp] == null)
{
break;
}
}
return temp;
}
blocksList是一个部分填充的数组,大小为4096。 该函数应该检查列表中的第一个空是空(null),因此它可以将此id传递给超级函数,该函数将id提供给基类,该基类使用此id创建对象并将其添加到blocksList。
此处调用函数getNextEmptyId():
public class ModBlock extends Block
{
...
public ModBlock(String name, Material material)
{
super(getNextEmptyId(), material);
GameRegistry.registerBlock(this, name);
this.setTextureName("terracraft/" + name);
this.setUnlocalizedName(name);
this.stepSound = soundStoneFootstep;
}
}
然后通过super再次调用此函数:
public Block(int par1, Material par2Material)
{
this.stepSound = soundPowderFootstep;
this.blockParticleGravity = 1.0F;
this.slipperiness = 0.6F;
if (blocksList[par1] != null)
{
throw new IllegalArgumentException("Slot " + par1 + " is already occupied by " + blocksList[par1] + " when adding " + this);
}
else
{
this.blockMaterial = par2Material;
blocksList[par1] = this;
this.blockID = par1;
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
opaqueCubeLookup[par1] = this.isOpaqueCube();
lightOpacity[par1] = this.isOpaqueCube() ? 255 : 0;
canBlockGrass[par1] = !par2Material.getCanBlockGrass();
}
}
在AABBPool第50行:
44 public AxisAlignedBB getAABB(double par1, double par3, double par5, double par7, double par9, double par11)
45 {
46 AxisAlignedBB axisalignedbb;
47
48 if (this.nextPoolIndex >= this.listAABB.size())
49 {
50 axisalignedbb = new AxisAlignedBB(par1, par3, par5, par7, par9, par11);
51 this.listAABB.add(axisalignedbb);
52 }
53 else
54 {
55 axisalignedbb = (AxisAlignedBB)this.listAABB.get(this.nextPoolIndex);
56 axisalignedbb.setBounds(par1, par3, par5, par7, par9, par11);
57 }
58
59 ++this.nextPoolIndex;
60 return axisalignedbb;
61 }
在Block 602中:
600 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
601 {
602 return AxisAlignedBB.getAABBPool().getAABB((double)par2 + this.minX, (double)par3 + this.minY, (double)par4 + this.minZ, (double)par2 + this.maxX, (double)par3 + this.maxY, (double)par4 + this.maxZ);
603 }
如果您需要更多信息,请说明。 谢谢你的帮助。
答案 0 :(得分:0)
第一眼看到您的问题不是寻找阻止列表中的差距的函数,而是您构建的每个块都在该列表和GameRegistry中被引用。
当你尝试释放一个块时,也许其中一个引用会以某种方式存在,这会阻止GC擦除其内存并导致泄漏...这只是一个想法,请检查它。
请查看Why does this code sample produce a memory leak?以获取有关内存泄漏的进一步说明