L’utilisation de la mémoire augmente constamment sous Windows

Je développe un jeu utilisant Java 1.6 avec le LWJGL. J’ai un MacBook Pro et un ordinateur de bureau Windows 8 et je code uniquement sur le MacBook. Aujourd’hui, j’ai décidé de tester mon jeu sur mon ordinateur de bureau et quelque chose de vraiment étrange s’est produit. Le Gestionnaire des tâches affiche une croissance constante de l’utilisation de la mémoire sur mon application. À un moment donné (autour de 700 Mo), tout l’ordinateur est vraiment lent, ce qui s’améliore après avoir tué mon processus de jeu. La partie étrange est que ce problème ne se produira ni sur Mac OSX 10.9 ni sur Windows 7 (Parallels Virtual Machine sur mon Mac). Comme j’utilise différents appels OpenGL, j’ai déjà utilisé OpenGL Profiler d’Apple et il ne semble y avoir aucun problème, tout se passe comme prévu.

J’ai également essayé d’parsingr mon application (sur mon bureau Windows 8) à l’aide de VisualVM qui montrait étrangement des résultats attendus: taille du tas stable et utilisation du tas.

Que peut-il se passer? Comment puis-je “déboguer” ceci?

Edit: Je viens de découvrir que le même problème se produit si je démarre Windows 7 au lieu d’utiliser Parallels Virtual Machine sur mon MacBook Pro. Je pense que le problème est lié à Windows.

Edit 2: J’ai testé le code en retirant des parties (le jeu est une grosse boucle à la fin de la journée) et j’ai remarqué que le problème se posait dans la partie la plus récente que j’ai codée: le Système d’éclairage. Il y a une fonction appelée toutes les 16ms appelée tick () dans chaque système. Si je vide la fonction tick () du système d’éclairage, le problème disparaît. J’ai essayé de supprimer des parties de la fonction de tique pour voir ce qui se passe. Cette fonction fonctionne en interrogeant les entités de jeu produisant de la lumière (et générant des ombres), puis rend réellement les textures d’ombre. Tout fonctionne correctement jusqu’à ce que je commence le processus de rendu, qui consiste en plusieurs passes de shaders, chacune ressemblant à ceci:

layer ‘, ‘ fbo ‘, ‘ distanceShader ‘ et ‘ distanceTexture ‘ sont des variables globales que je réutilise.

layer.setTexture(SpriteSheet.teste.getTexture()); //set the texture atlas layer.setShader(distanceShader); //set the shader fbo = new Framebuffer(new Vector2f(light.getCurrentRadius() * 2, light.getCurrentRadius() * 2), new Vector3f(1f, 1f, 1f), 0f); //generate a framebuffer object fbo.init(); //initialize it fbo.begin(); //begin the rendering step distanceShader.bind(); //bind the shader distanceShader.setUniform("transform", transform.getOrthographicTransformation(new Vector2f(position.getPosition().getXInt(), position.getPosition().getYInt()))); //pass info into the shader distanceShader.setUniformf("lightRadius", light.getCurrentRadius()); //pass info into the shader distanceShader.setUniformf("ambientLight", ambientLight); //pass info into the shader render(); //render the 'layer' fbo.end(); //end the rendering step distanceTexture = fbo.getTexture(); //keep a reference to the texture generated on the fbo, to which I rendered. it will be used in the next step's layer.setTexture() fbo.dispose(false); //free fbo's GPU memory (false means it's texture is not being disposed) 

Je le fais plusieurs fois, chaque étape utilise la texture générée à la dernière étape, et la fuite de mémoire possible se produit à ces morceaux de code. Si je ne laisse que le morceau que j’ai collé ici, j’ai le problème de mémoire. Si je laisse plus de pièces, je les reçois plus rapidement. Je devrais append que chaque texture (telle que ‘distanceTexture’ est disposée à la fin de la fonction tick ()).

  1. Vous pouvez utiliser l’parsingur de mémoire MAT http://www.eclipse.org/mat/ pour voir quels objects occupent la mémoire.

  2. Vous pouvez utiliser jconsole pour voir comment la mémoire est utilisée et combien de fois il faut GC, vous pouvez également forcer GC à voir s’il s’agit d’un problème de GC et forcer un GC à résoudre votre problème. Il se peut alors que certaines variables inutilisées ne soient pas récupérées. jconsole fait maintenant partie de java 7. Vous pouvez donc le lancer en entrant “jconsole &” dans votre ligne de commande.

  3. Si son object fbo occupe tout l’espace, j’appendais fbo = null comme dernière ligne.