This site requires JavaScript, please enable it in your browser!
Greenfoot back
Entity1037
Entity1037 wrote ...

2013/9/29

Out of heap space. What do I do?

Entity1037 Entity1037

2013/9/29

#
So I ran out of memory. Does anyone know why? Here's my error: java.lang.OutOfMemoryError: Java heap space at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75) at java.awt.image.Raster.createPackedRaster(Raster.java:470) at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032) at java.awt.GraphicsConfiguration.createCompatibleImage(GraphicsConfiguration.java:186) at greenfoot.util.GraphicsUtilities.createCompatibleTranslucentImage(GraphicsUtilities.java:179) at greenfoot.GreenfootImage.scale(GreenfootImage.java:403) at FadeOverlay.addedToWorld(FadeOverlay.java:10) at greenfoot.World.addObject(World.java:408) at XEngine.<init>(XEngine.java:24) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) Thank you.
Gevater_Tod4711 Gevater_Tod4711

2013/9/29

#
This error most times occours because you have to many objects or to many images that need much space in your RAM. I think this error is caused by the scaling of an actor that is added to the world. The problem with this errors is you can't realy do anything against them. You only can try to use less objects or images. (e.g. If you need one image for all objects in a class declare it static)
SPower SPower

2013/9/29

#
I have a lot of experience with the OutOfMemmoryError exception, so I'll give you some advice:
  • The thing which is easiest is replacing things like this:
    setImage(new GreenfootImage(100,100));
    with this:
    getImage().clear();
    getImage().scale(100,100);
    which will preserve a little memory, because you don't create an extra image. This won't work on the long term however, because the garbage collector will eventually remove your original image in the first example.
  • Something which needs a little more work, is using a Hashtable (java.util.Hashtable) to load all the images you need into memory, and then re-using the loaded images when you need them. An example:
    // at the top
    import java.util.Hashtable
    
    // inside the class
    private static final Hashtable<String, GreenfootImage> imgs = new Hashtable<String, GreenfootImage>();
    
    // load all of the images
    // the code inside the 'static {}' will get executed once: when you compile (or when the class get 'created' :D )
    static {
        imgs.put("image.png", new GreenfootImage("image.png"));
    }
    
    // you can now access the image.png
    GreenfootImage imageToUse = imgs.get("image.png");
I hope this helps :)
Entity1037 Entity1037

2013/9/29

#
Well it looks like I'm going to have to figure out how to program my own sprite sheet cutter because I'm attempting to make a game 100% programmed by myself, so I need to figure out how to do something or else I wont let myself let it in my game. I'm using this game as a tool to teach myself more programming skills. Smart, right? So, I think the error right now is unrelated to my X actor, but instead lies in my "textSelection" actor:
import greenfoot.*;
import java.awt.Color;

public class textSelection extends Actor
{
    String text;
    Color colour;
    Color normal;
    Color highlight;
    World load;
    public textSelection(String name,Color c,Color h,World world){text=name; normal=c; highlight=h; load=world;}
    public void addedToWorld(World world)  
    {
        updateImage();
    }
    
    public void act(){
        MouseInfo mouse = Greenfoot.getMouseInfo();
        if (mouse!=null&&mouse.getX()>getX()-getImage().getWidth()/2&&mouse.getX()<getX()+getImage().getWidth()/2&&mouse.getY()>getY()-getImage().getHeight()/2&&mouse.getY()<getY()+getImage().getHeight()/2){
            colour=highlight;
        }else{
            colour=normal;
        }
        if (Greenfoot.mouseClicked(this)){
            Greenfoot.setWorld(load);
        }
        updateImage();
    }
    private void updateImage()
    {
        setImage(new GreenfootImage(text, 30, colour, new Color(0, 0, 0, 0)));
    }
}
I think using pre-made images might make that much less taxing, correct? Also, I believe using a sprite sheet and Hashtable would tremendously help. Please correct me if I'm wrong.
davmac davmac

2013/9/30

#
What SPower and Gevater_Tod4711 say above may be true, but in this case, due to your stack trace, it looks possible that you may have unwittingly created infinite recursion: at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) at MainMenu.<init>(MainMenu.java:10) at XEngine.<init>(XEngine.java:26) So in your XEngine constructor, line 26, you are creating a MainMenu instance, and in your MainMenu constructor you are creating an XEngine instance (line 10). So you see, if you create one instance of either of those classes it will create an infinite number of objects - that's why you're running out of heap space.
Entity1037 Entity1037

2013/9/30

#
*facepalm* Thank you! So... I just need to make sure to create the instance when an event happens, instead of when the world loads... wow I feel stupid. :/
You need to login to post a reply.