我正在使用Java 1.6和LWJGL开发游戏。我有一台MacBook Pro和一台Windows 8台式电脑,我只在MacBook上编码。今天我决定在台式电脑上测试我的游戏,发生了一件非常奇怪的事。任务管理器显示我的应用程序的内存使用量不断增长。在某些时候(大约700MB),整个计算机变得非常慢,在我杀死我的游戏过程后变得更好。奇怪的是,这个问题既不会发生在Mac OSX 10.9上,也不会发生在Windows 7上(我Mac上的Parallels虚拟机)。当我使用不同的OpenGL调用时,我已经使用了Apple的OpenGL Profiler,似乎没有任何问题,一切都按预期显示。
我还尝试使用VisualVM分析我的应用程序(在我的Windows 8桌面上),奇怪地显示了期望的结果:稳定的堆大小和堆使用情况。
可能发生什么?我怎样才能“调试”这个?
修改 我刚刚发现,如果我启动Windows 7而不是在MacBook Pro上使用Parallels虚拟机,则会出现同样的问题。我认为这个问题与Windows有关。
编辑2: 我已经通过从中获取一些部分来测试代码(游戏在一天结束时是一个大循环)并且我注意到问题发生在我编码的最新部分:照明系统。每个系统内都有一个名为tick()的函数被称为tick()。如果我清空Lighting System的tick()函数,问题就会消失。我试图删除部分tick功能,看看会发生什么。此功能通过查询哪些游戏实体产生光(并生成阴影)然后实际渲染阴影纹理来工作。一切都运行正常,直到我开始渲染过程,其中包含几个着色器过程,每个过程看起来像这样:
'图层',' fbo ',' distanceShader '和' distanceTexture '是全局变量,我重新使用了。
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)
我这样做了几次,每一步都使用了最后一步生成的纹理,并且可能的内存泄漏发生在这些代码片段上。如果我只留下我粘贴在这里的那块,我就会遇到内存问题。如果我留下更多的碎片,我会更快。我应该补充一点,每个纹理(例如'distanceTexture'都放在tick()函数的末尾)。
答案 0 :(得分:1)
您可以使用内存分析器MAT http://www.eclipse.org/mat/来查看占用内存的对象。
您可以使用jconsole查看内存的使用方式以及GC的使用次数,您也可以强制GC查看是否存在GC问题并强制GC将解决您的问题。然后它可能只是一些未被垃圾收集的未使用的变量。 jconsole现在是java 7的一部分。所以你可以通过输入“jconsole&”来启动它。在您的命令行中。
如果它的fbo对象占用了所有空间,我会添加fbo = null作为最后一行。