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

2016/3/11

Java heap space

Vellyxenya Vellyxenya

2016/3/11

#
Hi, when I launch a new game in my scenario 2 times in a row without compilling it in between, it tells me: Java heap space and I have to restart the whole project. Another related problem is that if I compile the scenario many times in a row, there are more and more lags until it also tells me Java heap space. However, closing the project and restarting it, removes all the lags... Do you know why? Is there a way to remove all the stocked datas in the Java virtual machine so that it doesn't lag? Or is it another problem? Thank you
danpost danpost

2016/3/11

#
Usually, code that causes a Java heap space error is located in a World subclass (but, not always). Maybe you should show your World subclass code so it can be corrected or eliminated as to the reason it is happening.
Vellyxenya Vellyxenya

2016/3/12

#
Sometimes there's only written the Java Heap Space Error, and other times, it also indicates me my "Video.class" so I suppose the problem is from this one:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import greenfoot.*;
 
/**
 * Animation played at the beginning of a game
 */
public class Video extends Interface
{
    GreenfootImage i1 = new GreenfootImage("1.png");
    GreenfootImage i = new GreenfootImage("1.png");
    /**
     * Images used for the animation
     */
    GreenfootImage[] silks = new GreenfootImage[15];
    int counter;
    int alpha;
    int plus;
    public static boolean more;
    Cover cover = new Cover();
 
    /**
     * Initializes the images of the animation
     */
    public Video()
    {
        more = false;
        for(int i = 0; i<15; i++)
        {
            silks[i] = new GreenfootImage("1.png");
        }
        for(int i = 0; i<15; i++)
        {
            silks[i].scale((int)(i1.getWidth()*(10+i)/8), (int)(i1.getHeight()*(10+i)/10));
        }
    }
 
    public void act()
    {
        try
        {
            alpha++;
            if(alpha%20 == 0)
            {
                plus++;
            }
            counter++;
            if(counter == 10)
            {
                getWorld().addObject(cover, getWorld().getWidth()/2, getWorld().getHeight()/2);
            }
            setImage(silks[counter]);
            if(counter>4+plus)
            {
                counter = 0+plus;
            }
        }
        catch(ArrayIndexOutOfBoundsException e)
        {
            more = true;
        }
        try
        {
            if(more == true)
            {
                i.scale((int)(i.getWidth()*1.2), (int)(i.getHeight()*1.2));
                setImage(i);
            }
        }catch(OutOfMemoryError e)
        {
            this.removeTouching(Image.class);
            getImage().setTransparency(getImage().getTransparency()-5);
            i1 = null;
            i = null;
            silks = null;
            System.gc();
            getWorld().removeObject(this);
        }
        if(counter>12)
        {
            getImage().setTransparency(getImage().getTransparency()-3);
        }
    }   
}
Sometimes it works (after I've just compiled) but if I start 2-3 games in a row without compiling, it stops working with the java heap space error in the "silks.scale((int)(i1.getWidth()*(10+i)/8), (int)(i1.getHeight()*(10+i)/10));" (line 32). Thank you
danpost danpost

2016/3/12

#
How about the Interface class? If this class extends it, it is a part of this class. You need to show its code also.
Vellyxenya Vellyxenya

2016/3/12

#
Here it is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import greenfoot.*;
import java.util.List;
 
public class Interface extends Actor
{
    public int width = 750;
    public int height = 563;
    private double exactX;
    private double exactY;
     
    public boolean mouseOn()
    {
        MouseInfo mouse = Greenfoot.getMouseInfo();
        if(mouse != null)
        {
            if( (mouse.getX() < (getX()+ this.getImage().getWidth()/2)) &&
            (mouse.getX() > (getX()- this.getImage().getWidth()/2)) &&
            (mouse.getY() < (getY()+ this.getImage().getHeight()/2)) &&
            (mouse.getY() > (getY()- this.getImage().getHeight()/2)))
            {
                return true;
            }
        }
        return false;
    }
 
    public boolean isPaused()
    {
        List<Pause> pause = getWorld().getObjects(Pause.class);
        int length = pause.size();
        if (length==1)
        {
            return true;
        }
        return false;
    }
 
    public void setLocation(double x, double y)
    {
        exactX = x;
        exactY = y;
        super.setLocation((int) (x + 0.5), (int) (y + 0.5));
    }
 
    public void move(double distance)
    {
        double radians = Math.toRadians(getRotation());
        double dx = Math.cos(radians) * distance;
        double dy = Math.sin(radians) * distance;
        setLocation(exactX + dx, exactY + dy);
    }
     
}
danpost danpost

2016/3/12

#
Well, there is nothing in the Interface class that would cause a java heap space issue. I think it has to deal with the number of images you are creating; but, I cannot see how it would work one time and not the next. Do you have other classes that does a lot of image creation and/or large sound files being loaded?
Vellyxenya Vellyxenya

2016/3/12

#
The only other class that creates a lot of images is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import greenfoot.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.util.List;
import java.io.*;
 
public class PseudoAnim extends Interface
{
    GreenfootImage image;
    String ID;
    private int counter;
    int focusX;
    int focusY;
    Name name = new Name();
     
    public PseudoAnim()
    {
        focusX = 0;
        focusY = 0;
        image = new GreenfootImage(750, 563);
        counter = 0;
        try
        {
            FileInputStream fIn = new FileInputStream(System.getProperty("user.home")+"/datas.txt");
            BufferedReader textFile = new BufferedReader(new InputStreamReader(fIn));
            String line = "";
            for(int i = 0; i<Menu.account-1; i++)
            {
                textFile.readLine();
            }
            String infos = textFile.readLine();
            String[] splittedInfos = infos.split(" ");
            ID = splittedInfos[0];
            textFile.close();
        }
        catch(IOException e)
        {
            System.out.println("In-Game problem, can't read the file for the pseudo...");
        }
        image.setTransparency(50);
        image.setColor(Color.RED);
        int random = Greenfoot.getRandomNumber(7);
        Font f = new Font("Creepygirl", Font.BOLD, 30);
        image.setFont(f);
        FontMetrics fm = image.getAwtImage().getGraphics().getFontMetrics(f);
        setImage(image);
    }
 
    public void act()
    {
        counter++;
        if(counter%5 == 0)
        {
            for(int i=0; i<5; i++)
            {
                animate2();
            }
            if(focusX<375)
                focusX += 5;
            if(focusY<282)
                focusY += 4;
        }
    }
 
    public void animate2()
    {
        try
        {
            getWorld().addObject(new Names(), focusX+50+Greenfoot.getRandomNumber(650-2*focusX), focusY+10+Greenfoot.getRandomNumber(550-2*focusY));
        }
 
        catch(IllegalArgumentException e)
        {
            getWorld().addObject(name, getWorld().getWidth()/2, getWorld().getHeight()/2);
        }
    }
     
}
I would upload the whole project on greenfoot but it's too heave (120 Mo)
danpost danpost

2016/3/12

#
You are creating and adding five Names objects into the world every tenth of a second (about 50+ objects per second). This will quickly fill you heap space. Is there any code that will remove Names objects from the world? is it necessary to create so many so quickly? what do these Names objects do (maybe you could show its class code)?
Vellyxenya Vellyxenya

2016/3/13

#
In fact, it's just an animation, they appear very quickly and concentrate on the middle of the screen. After about 2-3 seconds, they spread and disappear. Is there a way to clear the java heap space after such objects being created? I tried System.gc() but I'm not sure if it really works. Here's the code for the Names.class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import greenfoot.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.io.*;
 
public class Names extends Interface
{
    GreenfootImage image = new GreenfootImage(280, 80);
    String ID;
    private int counter;
 
    public Names()
    {
        try
        {
            FileInputStream fIn = new FileInputStream(System.getProperty("user.home")+"/datas.txt");
            BufferedReader textFile = new BufferedReader(new InputStreamReader(fIn));
            String line = "";
            for(int i = 1; i<Menu.account; i++)
            {
                textFile.readLine();
            }
            String infos = textFile.readLine();
            String[] splittedInfos = infos.split(" ");
            ID = splittedInfos[0];
            textFile.close();
        }
        catch(IOException e)
        {
            System.out.println("In-Game problem, can't read the file for the pseudo...");
        }
        image.setTransparency(30+Greenfoot.getRandomNumber(80));
        image.setColor(Color.RED);
        Font f = new Font("Creepygirl", Font.BOLD, 30+Greenfoot.getRandomNumber(60));
        image.setFont(f);
        FontMetrics fm = image.getAwtImage().getGraphics().getFontMetrics(f);
        image.drawString(""+ID, 125-fm.stringWidth(""+ID)/2, 50);
        setImage(image);
        counter = 30;
    }
 
    public void act()
    {
        if(Intro.ready == true)
        {
            counter++;
            if(counter >= 120)
            {
                int rotation = this.getRotation();
                int angle;
                this.turnTowards((int)(getWorld().getWidth()/2), (int)(getWorld().getHeight()/2));
                if(counter<135) move(-2);
                else if(counter>=135 && counter <175) move(-3);
                else if(counter>=175 && counter <200) move(-4);
                else move(-5);
                setRotation(0);
                if(isAtEdge())
                {
                    getWorld().removeObject(this);
                }
            }
        }
    }
 
}
Thank you
danpost danpost

2016/3/13

#
Anything that can reduce the number and size of files within the project might help. Anything that can reduce the number of images used in your project might help (each Names object, which there are many, creates its own image, each being 200x80 in size). These are all memory extensive. What are the main contributors to the 120 Mo size of your project?
Vellyxenya Vellyxenya

2016/3/13

#
I checked again and after adding more sounds it's 250 Mo: 200Mo for the sounds 30Mo for the images 20Mo for the rest Didn't expect that the sounds would be so heavy
danpost danpost

2016/3/13

#
Vellyxenya wrote...
I checked again and after adding more sounds it's 250 Mo: 200Mo for the sounds 30Mo for the images 20Mo for the rest Didn't expect that the sounds would be so heavy
You could temporarily comment out all statements relating to sounds and remove the sound files from the project (saving them somewhere outside the project folder so you can re-import them later); then, see if you still have heap space issues.
You need to login to post a reply.