好的,我为我的A级计算项目设计了一个游戏,到目前为止,一切都还好。我完成了框架,当我得到一个java.lang.OutOfMemoryError: Java heap space
(下面的完全错误)时,我开始实现游戏。我以前从未经历过这种情况,但是这是否与我试图加载太多的静态变量有关呢?例如,我的每个级别都是静态的,每个级别都试图将600x600像素的图像呈现到地图中。由于它是静态的,这会导致内存崩溃转储吗?
以下是输出所述错误所在的几行代码:
SpriteSheet.java,第131行:
129 private void load() {
130 try {
131 image = ImageIO.read(SpriteSheet.class.getResource(path));
132 this.width = image.getWidth();
133 this.height = image.getHeight();
134 pixels = new int[this.width * this.height];
135 image.getRGB(0, 0, this.width, this.height, pixels, 0, this.width);
136 } catch (IOException e) {} catch (Exception e) {}
137 }
SpriteSheet.java第110行从构造函数调用上述方法。
敌人,第161行:
160 public void initSheets() {
161 SpriteSheet mainSheet = new SpriteSheet(sheet, 96, 128);
162 down = new AnimatedObject(new SpriteSheet(mainSheet, 0, 0, 3, 1, 32), 32, 32, 3);
163 up = new AnimatedObject(new SpriteSheet(mainSheet, 0, 3, 3, 1, 32), 32, 32, 3);
164 left = new AnimatedObject(new SpriteSheet(mainSheet, 0, 1, 3, 1, 32), 32, 32, 3);
165 right = new AnimatedObject(new SpriteSheet(mainSheet, 0, 2, 3, 1, 32), 32, 32, 3);
166 }
Zombie.java,第25行从构造函数调用上述方法。EnemySpawner.java,第35行创建了一个新的僵尸,其中调用了initSheets()
。
BossLevel.java,第42行:
38 protected void generateLevel(){
39 for (int x = 0; x < width; x++){
40 for (int y = 0; y < height; y++){
41 if (tiles[x + y * width] == Tile.col_enemy) {
42 EnemySpawner es = new EnemySpawner(x, y, 100, 5, this, bossName);
43 add(es);
44 } else if (tiles[x + y * width] == Tile.col_boss){
45 Boss bs = new Boss(x, y,health, "/textures/sheets/mob/enemy/" + bossName.toLowerCase() + "/king" + bossName + ".png");
46 add(bs);
47 }
48 }
49 }
50 }
最后,在Level.java中,这是生成我的级别的代码:
53 public static Level level1 = new BossLevel("/levels/level1.png", "Zombie", 60);
54 public static Level level2 = new LavaLevel("/levels/level2.png", "Mummy", 120);
55 public static Level level3 = new BossLevel("/levels/level1.png", "Goblin", 180);
56 public static Level level4 = new BossLevel("/levels/level1.png", "Mummy", 240);
57 public static Level level5 = new BossLevel("/levels/level1.png", "Goblin", 180);
58 public static Level level6 = new BossLevel("/levels/level1.png", "Zombie", 60);
59 public static Level spawn = new SpawnLevel("/levels/spawn.png");
..。
88 public static void initLevels(){
89 Level.level1 = new BossLevel("/levels/level1.png", "Zombie", 60);
90 Level.level2 = new LavaLevel("/levels/level1.png", "Mummy", 120);
91 Level.level3 = new BossLevel("/levels/level1.png", "Goblin", 180);
92 Level.level4 = new BossLevel("/levels/level1.png", "Mummy", 240);
93 Level.level5 = new BossLevel("/levels/level1.png", "Goblin", 180);
94 Level.level6 = new BossLevel("/levels/level1.png", "Zombie", 60);
95 Level.spawn = new SpawnLevel("/levels/spawn.png");
96 generatedPortals = false;
97 }
最后一件事,只有当我有6个等级时才会发生。如果我删除了第6级的代码,它可以正常工作,但游戏需要很长时间才能加载。有什么想法吗?
谢谢
系统规格:Celeron2.60GHz运行在3.7 GHz 4GBRAM Windows 10 x64位
发布于 2015-12-06 22:09:51
在java中,您不需要主动销毁级别,因为垃圾收集器会为您处理这个问题。
当对象不再可访问时(即没有指向它的变量,如果需要更多的内存,它将被移除)。问题是静态对象永远不会被移除,因为变量永远不会超出作用域,所以它永远存在,直到为变量赋值其他东西为止。
也许只有一个级别变量(静态或非静态)就足够了:
public static Level activeLevel
和一个函数
public static void loadLevel(int levelId) { ... activeLevel = new BossLevel(...); }
有了这一点,以前的水平将不再可达(activeLevel指向其他事物),并被删除。
现在你的游戏也应该更快的开始,因为它不需要加载所有的水平在开始。然而,在级别之间切换需要更多的时间,因为那时必须加载新的数据。
发布于 2015-12-06 21:50:18
好的,看看如何在Maven中设置堆大小(谢谢@Aracurunir),我找到了一个相当好的解决方案here。然而,该程序需要能够在许多系统上运行,这篇文章中列出的解决方案是特定于计算机的。这款游戏最终将在一所学校中使用,在各种系统规格上。
https://stackoverflow.com/questions/34123036
复制相似问题