I have a GameScreen and after end of the level I set the screen back to GameScreen as a restart when user taps restart button. I do this this.setScreen(new GameScreen(game)); and before I do that line of code I dispose the screen itself, all the textures used in screen, font files and so on, everything except box2D (world because disposing it gives me native error and makes the game crash ). But even though I dispose assets before I set screen game still crashes after 15-20 restarts.
I have analyzed the memory usage by printing JavaHeap, and found out that the momory usage increases in every restart until certain point and then gets back to low point like this:
- Restart1: 10MB
- Restart2: 13MB
- Restart3: 15MB
- Restart4: 10MB
- Restart5: 11MB
- Restart6: 14MB
- Restart7: 9MB
I have read about memory usage and found out that this kind of behavior is normal. But still my game crashes after few restarts without even giving error message.
What could be causing this?
EDIT: I tested the game on ZTE Blade and found out that the game gets slower by every reset, but still crashes in around 15-20 resets.
The memory up and down pattern is standard for garbage collection, you only have to worry if it starts being unable to reach the previous low point after a garbage collection as that would indicate a memory leak. It sounds like there might be something you aren't disposing of but why are you disposing anything if you are just going to reload all the same assets?
Switch to using the AssetManager. If you call AssetManager.load in your Screen constructor, AssetManager.finishLoading in your Screen.show method and AssetManager.unload in your Screen.hide method you should never unload any of your GameScreen assets because of how AssetManager does reference counting and you would only unload those assets if you navigated to a different screen. Don't forget to call `AssetManager.update in your render method.
You probably have solved your problem somehow since it has been almost a year but I will just put this here anyway, hopefully it may help people who are looking for solutions to this kind of errors.
I have a similar mechanism for one of my applications and I experienced a native crash with Box2d world too. It was when I used setScreen(new GameScreen(game)) after disposing the original one.
I used to have the following kind of initialization:
public class GameScreen implements Screen {
/*Global Variables*/
...
final private static World world = new World(new Vector2(0, 0), true); //Create a world with no gravity;
...
public GameScreen(SGM game){...}
It turned out that I have to initialize world in the constructor. Now I have the following working without any crash no matter how many times I dispose and recreate it:
public class GameScreen implements Screen {
/*Global Variables*/
...
final private static World world;
...
public MatchScreen(SGM game){
this.game = game;
world = new World(new Vector2(0, 0), true); //Create a world with no gravity
I'm not sure if that was also the cause in your case but well, it's just another suggestion.
Related
I have create a game app in libgdx and usually it works well, but sometimes it goes in slow motion, in my opinion is a RAM memory problem. I've a Main class that extends Game.class, in main class i create a play screen class, when the player died i create again the play screen class. I believe that the RAM memory that the memory has not released and after many death it accumulates, in fact if I run the application with the task manager open when the death increase memory also increases.
This is the code:
public class MyGdxGame extends Game(){
private PlayScreen play_screen;
private SpriteBatch batch;
public void create(){
batch=new SpriteBatch();
play_screen=new PlayScreen(this);
setScreen(play_screen);
}
public void render(){
if(play_screen.death==true){
play_screen=new PlayScreen(this);
setScreen(play_screen);
}
}
So I did a test:
public void render(){
do{
play_screen=null;
play_screen=new PlayScreen(this);
setScreen(play_screen);
}while(1!=2);
}
I ran the app with the task manager open, memory increases rapidly until it crashes. So how i can clean up the RAM memory?
Many LibGDX objects has to be manually cleared for memory, see this. They implement the interface Disposable which has the method #dispose().
I don't see you disposing any of your used resources, your SpriteBatch is one of these objects.
When you're done with it call batch.dispose(). Setting it to null afterwards is optional, but recommended because using a disposed resource might lead to unintended behavior. The code will look something like this, which should be called when you no longer need it:
if(batch != null) {
batch.dispose();
batch = null;
}
LibGDX memory leaks is almost ever because one or more resources was not disposed
So, I'm programming a basic TowerDefense game. It's coming together great, but I'm stuck trying to preload images. What my predicament is is that when I call the paint method for my Canvas class (it extends JPanel) it opens a thread called "Image Fetcher x" where 'x' is a number starting with 0 and going up for multiple instances of the thread. As far as I understand, this thread is taking the images from my image variables, locating them on the disk, loading them into RAM for my game to display, and then drawing them.
This works fine, however, in the middle of the game, there are moments where nothing appears because the draw method I call is attempting to draw an image which hasn't been loaded. Gameplay is still effective, but the visual representation is messed up because the player basically sees a grass block shooting an enemy. Then all of a sudden the image loads and is drawn and looks normal.
This is fine and all, but I want to be able to pre-load all the resources (and possibly make a loading screen so the player knows that the game is loading) so that the non-loaded images don't destroy the illusion of gameplay - if that makes sense. I have tried using a MediaTracker, that didn't work. I've researched this and can't seem to find anything anywhere on this.
My current code consists of arrays of images from an image map. Each image in an array is drawn on the canvas according to certain identifiers which tell the game which tile/tower to draw. I am using the java.awt.Image class to store my images. So, is there any way to preload my images so that they don't have to load mid-gameplay?
Thanks!
Edit:
Code:
for(int y=0; y<tileMap.length; y++) {
for(int x=0; x<tileMap[y].length; x++) {
tileMap[y][x] = new ImageIcon("res/tileMap.png").getImage();
tileMap[y][x] = createImage(new FilteredImageSource(tileMap[y][x].getSource(), new CropImageFilter(x * Room.blockSize, y * Room.blockSize, Room.blockSize, Room.blockSize)));
}
}
public void paintcomponent(Graphics g) {
g.drawImage(tileMap[1][2], 5, 7, null);
}
That's a simplified version, I have about 1500 lines so I don't think you want to see all that, lol. Basically, I just create the image variables and then draw them. At the point of drawing them, an Image Fetcher thread is initiated, loads the image and then disappears after the image has finished loading. While the image is loading (and the Image Fetcher thread is active) the drawImage method draws nothing since the image isn't preloaded into RAM. However, once it's done loading the image, the drawImage method actually draws the correct image and the Image Fetcher thread is no longer active. Is there a way to either initiate the Image Fetching process so that this all happens before starting the program?
I've also tried just drawing everything at the beginning, that didn't work since the program runs too fast for the Image Fetchers to successfully load every image before the user plays. idk, the Image Fetchers are complicated. I just need to know how to preload images into RAM.
The question is a bit of a throw off, as I don't mean disposing the screen itself. What I am using is an enum and switch statement to switch screens, rather than the Screen and Game classes. What I am really asking here is, when I switch from one game state to the other, am I supposed to dispose all of my disposables before hand? Or do I just keep all of them and not worry about it, despite not rendering them anymore since I'm rendering a separate screen? I'd find it annoying to have to dispose all the resources on my screen every single time I want to switch to another one, so I'm wondering if it's truly necessary.
It's your choice and type of your game(Is your game having many resources).
If having lots of resources then it's better to dispose resource of one screen then load resource of another screen in memory and after that use that resource.
In this scenario show loading screen and load resource asynchronously.
If don't having lots of resources, dispose resource only when you exit from your game. Inherited Game's dispose() is best place for dispose your game resource in this scenario and call screen dispose from here. so that screen specific resource can disposed.
Quick rules can be:
If you loading something (Texture, TextureAtlas, Music, Sound etc.) at application start and you do not have problem with memory heap - dispose it at application dispose method.
But if you loading something special for your screen at screen start you should dispose it in screen dispose method.
If you do not dispose resource for ex. Texture it will be still in memory even if you dont render it. When you loading some texture inside screen without dispose it inside screen dispose method, it maybe to cause a memory leak because you load same texture second time when you start your screen again.
I am creating a simple pet simulator, it is my first project created for an assignment. Most of the functionality is working fine, I have re-written it many times as I have gotten better at setting out projects, however while adding in a timer I have encountered a massive floor.
After running the project my game seems to work fine, images are being rendered (Perhaps not the most efficiently) and my timer/FPS counter works well. However ever since I have added this timing/FPS code, it has been slowly getting slower and slower in FPS and then freezing up and crashing.
I followed Ninja Cave's timing tutorial for LWJGL. http://ninjacave.com/lwjglbasics4
Here is my source code, not all classes are included as there are quite a few, but can if need be. I have tried to just include the rendering focussed ones.
Main Class
http://pastebin.com/BpkHHnnj
Rendering Class
http://pastebin.com/QtJeYw1a
Texture Loader Class
http://pastebin.com/RX5iDXQm
Main Game State Class
http://pastebin.com/pvgDLkeM
The Pet Class
http://pastebin.com/VF6cq9S4
Thanks
I'm currently working on fixing your issue, but your renderer.readyTexture() just spins wildly out of control, and is essentially leaking memory, and fast, which explains the drop in speed.
Edit: I got the memory usage to stabilize.
Add public Map<String, Texture> loadedTextures = new HashMap<String, Texture>(); to your renderer class in render.java and change your renderer.readyTexture() method to this:
public void readyTexture(String textureDir){
if (!loadedTextures.containsKey(textureDir) || loadedTextures.get(textureDir) == null) {
texture = lt.loadTexture(textureDir);
loadedTextures.put(textureDir, texture);
} else {
texture = loadedTextures.get(textureDir);
}
textureDirString = textureDir;
texture.bind();
texLoaded = true;
System.out.println("Loaded: " + textureDirString);
}
Now that you have the code, the Map/HashMap stores the already loaded textures. In the renderer.readyTexture() method, I have it check if the Map does not contain the key textureDir and if it does, I check to see if it is null. If the entry is not in the Map or the contained Texture is null, we load the texture, and store it in the map. If the texture is stored, we pull it out from the Map and bind it.
Before, you were loading up the image every time, and the garbage collector was not removing it, this is possibly an issue with Slick, but if you cache everything properly, it works just fine.
I hope this helps.
I am trying to make an OpenGL game which has say 3 stages: Welcome, Battle and Armor. Each stage has different logic and works with different textures.
When is the best time to load those textures, all in the beginning, or load the ones that are used by each stage when it is activated. If so, should I then delete them when switching to another stage?
If the second method is best, how can I show static splash screen (image) while loading the textures per each stage?
Well, loading texture (especially from the sd card) can take time. The reason to load them before you need them is to avoid having a loading screen between stages. If the player will often switch between stages, and your texture are not so big, you might want to load them at startup (giving the pain of waiting for the game to load only once, even if it would be longer). You have to balance your choice between the memory that is available for you, and how much you want to piss the player by interrupting him in his playing experience.
You could also distract the player by displaying a scoreboard at the end of a stage to show him how good he's just been, instead of a loading bar.
If you can anticipate when the player will soon switch to another stage, you can try to stream the texture in background a little before, but it's a lot more complicated to do (well, especially on a mobile platform), so you'd need to do some research for that.
I think you should load them only if they are needed for that stage. Why waste memory by loading textures on your Video RAM if the player may not make it to the next stage?
You can show a dialog which is custom to your needs and dismiss it when you are ready. I don't have any samples right now.