图像检索和存储导致RAM使用过多

时间:2015-02-07 18:48:11

标签: java image memory jar ram

我已经搜索了几天寻找一个可行且合理的解决方案来与我的游戏进行交互,以简化我对图像的内存使用。当我注意到它需要太多RAM时,我正在分析我的2D回合制策略。我的问题是如何将我的游戏资源(总计为36MB的JAR)从600-800MB RAM转换为更加预期的50MB运行时间。我已经看到删除我的MediaTracker大大减少了RAM,我知道这是必要的。除了引用这个静态类以使用已经存储的图像之外,我没有其他类与图像混淆。

不用多说,我会提供我的代码,我希望你会发现这些代码很容易阅读。

package editor;

import java.awt.Font;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.imageio.ImageIO;

/**
 *
 * @author Darryl Thomas Idle
 */
public final class ResourceStash {

public static Map<String, Image[]> CHARMAP;
public static Map<String, Image[]> ITEMMAP;
public static Map<String, Sound>   SOUNDS;
public static Map<String, Image[]> TILEMAP;
public static Map<String, Image> UIMAP;
public static Map<String, Image> GLARES;
public Font font;

protected EditorEngine engine;
protected MediaTracker media;

public ResourceStash(EditorEngine engine){
    CHARMAP = new HashMap<>();
    SOUNDS = new HashMap<>();
    TILEMAP = new HashMap<>();
    ITEMMAP = new HashMap<>();
    UIMAP = new HashMap<>();
    GLARES = new HashMap<>();
    this.engine = engine;
    media = new MediaTracker(engine);
    try{
        font = Font.createFont(Font.TRUETYPE_FONT, this.getClass().getResourceAsStream("fonts/EngineerHand.ttf"));
        addSound(SOUNDS, "button_press.wav");
        addSound(SOUNDS, "ambience.mp3");
        addSound(SOUNDS, "grass_step.mp3");
        addAnimation(CHARMAP, CharacterObject.WALKDL, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUL, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUR, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.WALKDR, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDL, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUL, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUR, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDR, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDL, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUL, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUR, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDR, CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A1DL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A1DR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A1UL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A1UR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A2DL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A2DR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A2UL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A2UR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A3DL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A3DR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A3UL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A3UR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A4DL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A4DR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A4UL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A4UR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A5DL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A5DR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A5UL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A5UR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A6DL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A6DR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A6UL,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.A6UR,  CharacterObject.DUSKWITCH, 10);
        addAnimation(CHARMAP, CharacterObject.DEATHDL, CharacterObject.DUSKWITCH, 10);

        addAnimation(CHARMAP, CharacterObject.WALKDL, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUL, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUR, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.WALKDR, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDL, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUL, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUR, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDR, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDL, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUL, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUR, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDR, CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.A1DL,  CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.A1DR,  CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.A1UL,  CharacterObject.TINKERER, 10);
        addAnimation(CHARMAP, CharacterObject.A1UR,  CharacterObject.TINKERER, 10);

        addAnimation(CHARMAP, CharacterObject.WALKDL, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUL, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUR, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.WALKDR, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDL, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUL, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUR, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDR, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDL, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUL, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUR, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDR, CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A1DL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A1DR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A1UL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A1UR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A2DL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A2DR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A2UL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A2UR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A3DL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A3DR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A3UL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A3UR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A4DL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A4DR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A4UL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A4UR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A5DL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A5DR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A5UL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A5UR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A6DL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A6DR,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A6UL,  CharacterObject.HOPLITE, 10);
        addAnimation(CHARMAP, CharacterObject.A6UR,  CharacterObject.HOPLITE, 10);

        addAnimation(CHARMAP, CharacterObject.WALKDL, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUL, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.WALKUR, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.WALKDR, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDL, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUL, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDUR, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMDDR, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDL, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUL, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPUR, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.JUMPDR, CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.A1DL,  CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.A1DR,  CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.A1UL,  CharacterObject.SHADOWYCONTENDER, 10);
        addAnimation(CHARMAP, CharacterObject.A1UR,  CharacterObject.SHADOWYCONTENDER, 10);
        addTileImgs(TILEMAP, "AIR", 1);
        addTileImgs(TILEMAP, "DIRT", 1);
        addTileImgs(TILEMAP, "DIRT_SEL", 1);
        addTileImgs(TILEMAP, "COBBLE", 1);
        addTileImgs(TILEMAP, "COBBLE_SEL", 1);
        addTileImgs(TILEMAP, "FROST", 1);
        addTileImgs(TILEMAP, "FROST_SEL", 1);
        addTileImgs(TILEMAP, "GRASS", 1);
        addTileImgs(TILEMAP, "GRASS_SEL", 1);
        addTileImgs(TILEMAP, "SAND", 1);
        addTileImgs(TILEMAP, "SCORCHED", 1);
        addTileImgs(TILEMAP, "SCORCHED_SEL", 1);
        addTileImgs(TILEMAP, "WATER", 30);
        addTileImgs(TILEMAP, "WATER_SEL", 30);
        addTileImgs(TILEMAP, "LAVA", 30);
        addItemImgs(ITEMMAP, "TREE", 1);
        addItemImgs(ITEMMAP, "TREE_SEL", 1);
        addItemImgs(ITEMMAP, "SPAWN", 1);
        addItemImgs(ITEMMAP, "SPAWN_SEL", 1);
        addItemImgs(ITEMMAP, "BUSH", 1);
        addItemImgs(ITEMMAP, "BUSH_SEL", 1);
        addItemImgs(ITEMMAP, "LIGHT", 1);
        addItemImgs(ITEMMAP, "LIGHT_SEL", 1);
        addUIImage(UIMAP, "mappreview", "leftbutton");
        addUIImage(UIMAP, "mappreview", "rightbutton");
        addUIImage(UIMAP, "mappreview", "pane");
        addUIImage(UIMAP, "layout", "frameui");
        addUIImage(UIMAP, "camera", "00");
        addUIImage(UIMAP, "portraits", "DUSKWITCH");
        addUIImage(UIMAP, "portraits", "HOPLITE");
        addUIImage(UIMAP, "portraits", "TINKERER");
        addUIImage(UIMAP, "portraits", "SHADOWYCONTENDER");
        addUIImage(UIMAP, "portraits", "UNKNOWN");
        addUIImage(GLARES, "glares", "00");
        int pos = 0;
        for(Entry<String, Image[]> imageEntry: CHARMAP.entrySet()){
            int i = 0;
            for(; i < imageEntry.getValue().length; i++)
                media.addImage(imageEntry.getValue()[i], i+pos);
            pos += i;
        }
        for(Entry<String, Image[]> imageEntry: TILEMAP.entrySet()){
            int i = 0;
            for(; i < imageEntry.getValue().length; i++)
                media.addImage(imageEntry.getValue()[i], i+pos);
            pos += i;
        }
        for(Entry<String, Image[]> imageEntry: ITEMMAP.entrySet()){
            int i = 0;
            for(; i < imageEntry.getValue().length; i++)
                media.addImage(imageEntry.getValue()[i], i+pos);
            pos += i;
        }
        for(Entry<String, Image> imageEntry: UIMAP.entrySet())
            media.addImage(imageEntry.getValue(), pos++);
        media.waitForAll(2000);
    }catch(Exception ex){ex.printStackTrace(System.out);}
}
private void addAnimation(Map<String, Image[]> map, String animation, String characterType, int frameCount){
    try{
        Toolkit tk = Toolkit.getDefaultToolkit();
        Image[] returnImgs = new Image[frameCount];
        for(int i = 0; i < frameCount; i++){
            Image image = null;
            //System.out.println(this.getClass().getResource("images/characters/"+characterType+"/"+animation+"/0"+i+".png").getPath());
            if(i < 10) image = tk.getImage(this.getClass().getResource("images/characters/"+characterType+"/"+animation+"/0"+i+".png"));
            else image = tk.getImage(this.getClass().getResource("images/characters/"+characterType+"/"+animation+"/"+i+".png"));
            returnImgs[i] = image;
        }
        map.put(characterType+animation, returnImgs);
    }catch(Exception ex){ex.printStackTrace(System.out);}
}
private void addItemImgs(Map<String, Image[]> map, String itemType, int frameCount){
    try{
        Toolkit tk = Toolkit.getDefaultToolkit();
        Image[] returnImgs = new Image[frameCount];
        for(int i = 0; i < frameCount; i++){
            Image image = null;
            //System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation()+"images/items/"+itemType+"/"+"0"+i);
            if(i < 10) image = tk.getImage(this.getClass().getResource("images/items/"+itemType+"/"+"0"+i+".png"));
            else image = tk.getImage(this.getClass().getResource("images/items/"+itemType+"/"+i+".png"));
            returnImgs[i] = image;
        }
        map.put(itemType, returnImgs);
    }catch(Exception ex){ex.printStackTrace(System.out);}
}
private void addSound(Map<String, Sound> sounds, String soundName){
    try{
        //System.out.println(this.getClass().getResource("sounds/"+soundName).toURI().toString());
        Sound sound = new Sound(this.getClass().getResource("sounds/"+soundName).toURI().toString(), false);
        sounds.put(soundName, sound);
    }catch(Exception ex){ex.printStackTrace(System.out);}
}
private void addTileImgs(Map<String, Image[]> map, String tileType, int frameCount){
    try{
        Toolkit tk = Toolkit.getDefaultToolkit();
        Image[] returnImgs = new Image[frameCount];
        for(int i = 0; i < frameCount; i++){
            Image image = null;
            //System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation()+"images/tiles/"+tileType+"/"+"0"+i);
            if(i < 10) image = tk.getImage(this.getClass().getResource("images/tiles/"+tileType+"/"+"0"+i+".png"));
            else image = tk.getImage(this.getClass().getResource("images/tiles/"+tileType+"/"+i+".png"));
            returnImgs[i] = image;
        }
        map.put(tileType, returnImgs);
    }catch(Exception ex){ex.printStackTrace(System.out);}
}
private void addUIImage(Map<String, Image> map, String uiName, String partOfUI) {
    try{
        //System.out.println(this.getClass().getResource("images/"+uiName+"/"+partOfUI+".png").getPath());
        Image image =   ImageIO.read(this.getClass().getResource("images/"+uiName+"  /"+partOfUI+".png"));
        map.put(uiName+partOfUI, image);
    }catch(Exception ex){ex.printStackTrace(System.out);}
}
}

2 个答案:

答案 0 :(得分:0)

Java JVM将(默认情况下)为缓存及其自身使用分配相当大量的内存。您可以使用-Xmx选项

调整用于heap size的RAM量
  

-Xmx512m

将JVM配置为不使用超过512 MB的堆。从链接页面

  

最大堆

     

小于1/4的物理内存或1GB。在J2SE 5.0之前,默认的最大堆大小为64MB。您可以使用-Xmx命令行选项覆盖此默认值。

答案 1 :(得分:0)

当您将图像读入内存时,它会在未压缩的内存中保存。您正在阅读的所有图像似乎都是压缩的png文件。这意味着您将消耗比文件大小更多的内存。

看来你有1200多张图片。可能使用的内存量最少为每像素约4个字节(每个像素表示为int)。