Game Heap Space - Out Of Memory Error

Hi there,

Ive completed my pacman/space invaders hybrid game- which has a main game and two playable videos. Its all fine, but when I go to run it it says;

Exception in thread "Image Fetcher 1" java.lang.OutOfMemoryError: Java heap space

Exception in thread "Image Fetcher 2" java.lang.OutOfMemoryError: Java heap space

Ive come to realise that this error is from the amount of data used to make up the game/video with there being around 150 images for the videos. Ive temporarily corrected this problem by making each video 26 images long (2.6secs each) but to get the full experience the user need to see around 75images.

After a bit of research I found that i needed to increase my 'heap space'- and I attempted to do this thru cmd, attemptin to increase it to 512mb.

The problem is the game doesnt have a main, or at least not one that I nor the computer can locate. And to get the heap space to increase it needs a main?!

I honestly dont know what I am doing here- but could anyone tell me how I can increase my heap space or locate a main? Im really confused!

Any help appreciated

Senor-Cojones

[1166 byte] By [Senor-cojonesa] at [2007-11-26 13:55:59]
# 1

By the way- the game is split up into 6 .class/.java files and a .html file. The code for the videos is ;

// load up the images for the movie

Image movieImages[] = new Image[27];

for (int i=0; i<movieImages.length; i++) {

movieImages[i] = getImage(getDocumentBase(), "../media/movie" + (i+1) + ".jpg");

theTracker.addImage(movieImages[i], i);

}

// load up the images for the second movie

Image movieImages2[] = new Image[27];

for (int i=0; i><movieImages2.length; i++) {

movieImages2[i] = getImage(getDocumentBase(), "../media/firingGun" + (i+1) + ".jpg");

theTracker.addImage(movieImages2[i], i);

}

and each video needs around 75 images- not 27 as above ^^^

Any help would really make my day as its just this to finalise the first game ive ever programmed in java! And ive only really been doing this around 10weeks- never touched it before in my life (hence why I make some basic errors!)

Thanx!>

Senor-cojonesa at 2007-7-8 1:35:16 > top of Java-index,Other Topics,Java Game Development...
# 2

I'd advise a more logical approach...

Instead of trying to increase heap space, use what you've got and nourish the true abilities of java by using threads YEY!!!

Heres the idea... have an array of about 20-30 images that are preloaded before you begin playing the movie, then as the movies plays DELETE the flast frame and shift all the other components back by one.. this is easily done with a 'java.util.ArrayList' or even just a List. Now u get rid of unneeded images and load new ones with a thread pool ( to avoid the movies being choppy ).

java.util.List loaded_images = new java.util.ArrayList();

java.util.List pool_images = new java.util.ArrayList();

....

... //load first 20 images.. however u want

...

while ( stillNeedToPlayMovie )

{

displayAsCurrentFrame( loaded_images.get(0) ); //always get first element

//the elements will always shift down in a list as the first is erased

loaded_images.remove( 0 ); //remove element that was displayed

addToPool( nextPicture ); //add next picture to be loaded to the Thread Pool

}

...

...

...

public void addToPool( BufferedImage bi )

{

pool_images.add( bi );

}

...

...

...

//somewhere in the thread class

public void run()

{

while ( true )

{

if ( someThingToLoad )

{

loaded_images.add(LoadMe(pool_images.get(indexToLoad)));

pool_images.remove( indexToLoad );

}

}

}

Note: a more efficient way would be to use the ArrayBlockingQueue Class which i completely didn't feel like putting here

ArikArikArika at 2007-7-8 1:35:16 > top of Java-index,Other Topics,Java Game Development...
# 3

Thanks for your help ArikArikArik, the problem with that method is.... 1. im not too sure how to use it :P and 2. In my original code the images are added to the tracker which waits from all the images to be loaded before it continues.

import javax.swing.*;

import java.applet.AudioClip;

import java.awt.*;

public class ICGGSApplet extends JApplet implements Runnable {

// constants describing possible game states

private static final int SHOW_MOVIE = 1;

private static final int PLAY_GAME = 2;

private static final int STOPPED = 3;

private static final int SHOW_MOVIE2 = 4;

private int gameState;// the current game state

private String name;// the player's name

private long frameStartTime; // the time the last frame was displayed

private Thread gameLoop;// thread to run the game and movie

// associated objects

private Movie theMovie;// Panel to display the movie

private MonsterGame theGame; // Panel to display the game

private ICGGSPanel currentPanel; // the currently displayed Panel (can be null)

private Movie2 theMovie2; // Panel to display the second movie

/**

* Called when applet is first loaded

* sets up the attributes, load media, creates game objects

* and sets up interface

*/

public void init() {

// neither the movie nor the game is currently playing

currentPanel = null;

gameState = STOPPED;

name = "";

// load up the audio files

AudioClip theAudio = getAudioClip(getDocumentBase(), "../media/shock.wav");

AudioClip theAudio2 = getAudioClip(getDocumentBase(), "../media/applause.wav");

AudioClip theAudio3 = getAudioClip(getDocumentBase(), "../media/bomb.wav");

AudioClip theAudio4 = getAudioClip(getDocumentBase(), "../media/cashtill.wav");

AudioClip theAudio5 = getAudioClip(getDocumentBase(), "../media/pacman.wav");

// create a media tracker to monitor the loading of the images

MediaTracker theTracker = new MediaTracker(this);

// load up the images for the movie

Image movieImages[] = new Image[25];

for (int i=0; i<movieImages.length; i++) {

movieImages[i] = getImage(getDocumentBase(), "../media/movie" + (i+1) + ".jpg");

theTracker.addImage(movieImages[i], i);

}

// load up the images for the second movie

Image movieImages2[] = new Image[25];

for (int i=0; i><movieImages2.length; i++) {

movieImages2[i] = getImage(getDocumentBase(), "../media/firingGun" + (i+1) + ".jpg");

theTracker.addImage(movieImages2[i], i);

}

// load up the images for the munchies

Image image1 = getImage(getDocumentBase(), "../media/munchie1.gif");

theTracker.addImage(image1, 4);

Image image2 = getImage(getDocumentBase(), "../media/munchie2.gif");

theTracker.addImage(image2, 5);

Image image3 = getImage(getDocumentBase(), "../media/munchie3.gif");

theTracker.addImage(image3, 6);

// wait for all the images to be loaded

try {

theTracker.waitForAll();

} catch (InterruptedException e) {

}

// create the movie object

theMovie = new Movie(movieImages);

theMovie2 = new Movie2(movieImages2);

// create the game object

theGame = new MonsterGame(image1, image2, image3, theAudio, theAudio2, theAudio3, theAudio4, theAudio5);

this.getContentPane().setBackground(Color.WHITE);

// Initialise key-input functionality

addKeyListener(new Input());// add keyboard listener to applet

}

/**

* Called when the Applet is ready to start executing

*/

public void start() {

// ask the user for their name

name = JOptionPane.showInputDialog(this, "What is your name?");

// start running the movie/game animation

if (gameLoop == null) {

gameLoop = new Thread(this);

gameLoop.start();

}

}

/**

* Called when the gameLoop thread is started

* loops continuously until user quits

*/

public void run() {

int input = Input.NONE;

// game loop

while (input != Input.QUIT) {

// what is the current time?

frameStartTime = System.currentTimeMillis();

input = checkInput();

if (gameState != STOPPED) // only necessary if the movie or game is showing

{

currentPanel.processInput(input);

currentPanel.update();

currentPanel.repaint();

} else

showStatus("Press 'G' to start game, 'M' to show movie or 'F' to show the second movie");

frameDelay(100);

}

}

/**

* called when the Applet is stopped

* stops the gameLoop thread

*/

public void stop() {

if (gameLoop != null) {

gameLoop.interrupt();// stops the animation thread

gameLoop = null;

}

}

/**

* called from the gameLoop

* checks for the last key stroke input by the user

* @return int - Input class constant representing user input

*/

public int checkInput() {

int input = Input.checkUserInput();

switch (input) // how the input is handled depends on the current game state

{

case Input.GAME:

// the user wants to play the game

if (gameState == STOPPED) // not currently playing a game or movie

{

// display the panel showing the game

currentPanel = theGame;

this.getContentPane().add(BorderLayout.CENTER, currentPanel);

this.validate();

// set up a new game

theGame.resetGame();

gameState = PLAY_GAME;

showStatus("Use arrow keys to move Monster, S key to stop");

} // otherwise ignore

break;

case Input.MOVIE:

// the user wants to see the movie

if (gameState == STOPPED) // not currently playing a game or movie

{

// display the panel showing the movie

currentPanel = theMovie;

this.getContentPane().add(BorderLayout.CENTER, currentPanel);

this.validate();

gameState = SHOW_MOVIE;

showStatus("Press S key to stop");

} // otherwise ignore

break;

case Input.MOVIE2:

// the user wants to see the second movie

if (gameState == STOPPED) // not currently playing a game or movie

{

// display the panel showing the movie

currentPanel = theMovie2;

this.getContentPane().add(BorderLayout.CENTER, currentPanel);

this.validate();

gameState = SHOW_MOVIE2;

showStatus("Press S key to stop");

} // otherwise ignore

break;

case Input.STOP:

// the user wants to stop the movie or game being shown

if (gameState == SHOW_MOVIE ) {

this.getContentPane().remove(currentPanel);

currentPanel = null;

JOptionPane.showMessageDialog(this,

"OK " + name + " I've stopped the movie");

} else if (gameState == PLAY_GAME) {

this.getContentPane().remove(currentPanel);

currentPanel = null;

JOptionPane.showMessageDialog(this,

"OK " + name + " I've stopped the game");

} else if (gameState == SHOW_MOVIE2 ) {

this.getContentPane().remove(currentPanel);

currentPanel = null;

JOptionPane.showMessageDialog(this,

"OK " + name + " I've stopped the movie"); }

gameState = STOPPED;

showStatus("Press 'G' to start game, 'M' to show movie");

break;

}

Input.reset(); // reset the input module

requestFocus();

this.repaint(); // redisplay the applet

return input; // return for further processing (eg to control movement of Monster)

}

/**

* called from the gameLoop

* pauses between frames

* @param millis long - minimum frame time

*/

public void frameDelay(long millis) {

long currentTime = System.currentTimeMillis(); // what time is it now?

long elapsedTime = frameStartTime - currentTime; // how long has it been since the start of the frame?

if (elapsedTime >< millis) // is it time to showing the new frame yet?

try {

Thread.sleep(millis - elapsedTime); // pause for the remaining time

} catch(Exception e) {

}

}}

Thats the whole code for the applet- preloadin the image (and also everything that doesnt relate to this problem lol). Ive asked around and the answer I was given I wasnt satisfied with- make the files smaller/delete some- the files are already at their smallest about 10kb each. And also apparently (I didnt know this...) but due to security restirictions I wouldnt be able to increase the heap size anyway (this is to run the applet on my own... and others computers).

So Im really too sure what to do at the minute. Anymore help would be appreciated though.

Thank you!

Senor-Cojones

Senor-cojonesa at 2007-7-8 1:35:16 > top of Java-index,Other Topics,Java Game Development...