*Hey… i think i found a strange MemoryLeak within lwjgl code. * …forget about
I'm trying to change the texture of an object at a KeyEvent.
My purpose is a virtual presentation, so for that i use a PdfRenderer which creates an image of each pdfFile.
I recognized that the memoryallocation raises with each change of texture… until a OutOfMemoryException occurs.
So i build a little test.
All you have to do is to create 17 jpgs named and placed in c:imgtmp0.jpg (tmp16.jpg)
In my testcase the jpgs are 1024x1024, ~200kb each.
You switch the texture by the right/left arrow key.
I'll be thankfull if anyone might verify this.
In addition i run the tptp Profiler in Eclipse, where i recognized that this leak seems to be within the MipMap class of lwjgl.
Here a testCase, and below some screens of profiling results. In this case the OutOfMemoryException occurs at #14, if i don't change the VM's heapsize.
package test;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import jmetest.effects.TestProjectedTexture;
import com.jme.app.SimpleGame;
import com.jme.image.Texture;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.BillboardNode;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.CullState;
import com.jme.scene.state.ShadeState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;
/**
* <code>TestProjectedTexture</code>
*
* @author Rikard Herlitz (MrCoder)
*/
public class VerifyMemoryLeakScaleImage extends SimpleGame
{
private static final Logger logger = Logger.getLogger(VerifyMemoryLeakScaleImage.class.getName());
private Texture projectedTexture2;
private TextureState ts;
private Quad frame;
private boolean switchPage = false;
private int desiredImageWidth;
private int currentPage = 0;
private int nextPage = 1;
public VerifyMemoryLeakScaleImage()
{
super();
desiredImageWidth = 1280;
}
protected void simpleUpdate()
{
if (KeyBindingManager.getKeyBindingManager().isValidCommand("nextPdfPage", false) && currentPage < 15)
{
switchPage = true;
nextPage = (currentPage + 1);
System.out.println(currentPage + "/" + nextPage);
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("lastPdfPage", false) && currentPage > 0)
{
switchPage = true;
nextPage = (currentPage - 1);
System.out.println(currentPage + "/" + nextPage);
}
if (switchPage)
{
System.out.println("prepare to show pdfPage: " + nextPage);
if (nextPage > 0 || (nextPage < 15))
{
String path = "c:\img\tmp" + nextPage + ".jpg";
System.out.println("try to load image: " + path);
projectedTexture2 = TextureManager.loadTexture(path, Texture.MM_NONE, Texture.FM_NEAREST, 8, true);
ts = display.getDisplaySystem().getRenderer().createTextureState();
ts.setTexture(projectedTexture2, 0);
frame.setRenderState(ts);
frame.updateRenderState();
currentPage = nextPage;
switchPage = false;
}
}
}
protected void simpleInitGame()
{
cam.setFrustumFar(40000);
try
{
try
{
ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, new SimpleResourceLocator(
TestProjectedTexture.class.getClassLoader().getResource("")));
}
catch (URISyntaxException e1)
{
logger.log(Level.WARNING, "unable to setup texture directory.", e1);
}
display.setTitle("Projected Texture Test");
cam.getLocation().set(new Vector3f(50, 50, 0));
cam.lookAt(new Vector3f(), Vector3f.UNIT_Y);
CullState cs = display.getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
cs.setEnabled(true);
Renderer r = display.getRenderer();
ShadeState s = r.createShadeState();
s.setShade(ShadeState.SM_FLAT);
String path = "c:\img\tmp" + currentPage + ".jpg";
projectedTexture2 = TextureManager.loadTexture(path, Texture.MM_NONE, Texture.FM_NEAREST, 8, true);
// projectedTexture2.setScale(new Vector3f(0.75f, 0.75f, 0.75f));
ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
ts.setTexture(projectedTexture2, 0);
frame = new Quad("frame", 300, 300);
// frame.setLocalRotation(new Quaternion().fromAngleAxis(45,
// Vector3f.UNIT_Y));
frame.getLocalTranslation().y = 150;
frame.setRenderQueueMode(com.jme.renderer.Renderer.QUEUE_OPAQUE);
frame.setRenderState(cs);
frame.setRenderState(ts);
// rootNode.attachChild(frame);
BillboardNode billboardNode = new BillboardNode("bbNode");
billboardNode.attachChild(frame);
billboardNode.setAlignment(BillboardNode.AXIAL);
rootNode.attachChild(billboardNode);
Box floor = new Box("b", Vector3f.ZERO, 200, 1, 200);
rootNode.attachChild(floor);
TextureState ts2 = display.getRenderer().createTextureState();
ts2.setEnabled(true);
Texture t1 = TextureManager.loadTexture(VerifyMemoryLeakScaleImage.class.getClassLoader().getResource(
"jmetest/data/texture/Detail.jpg"), Texture.MM_LINEAR, Texture.FM_LINEAR);
ts2.setTexture(t1, 0);
t1.setApply(Texture.AM_COMBINE);
t1.setCombineFuncRGB(Texture.ACF_MODULATE);
t1.setCombineSrc0RGB(Texture.ACS_TEXTURE);
t1.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
t1.setCombineSrc1RGB(Texture.ACS_PRIMARY_COLOR);
t1.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
t1.setCombineScaleRGB(1.0f);
floor.setRenderState(ts2);
}
catch (Exception e)
{
logger.logp(Level.SEVERE, this.getClass().toString(), "simpleInitGame()", "Exception", e);
}
KeyBindingManager.getKeyBindingManager().add("nextPdfPage", KeyInput.KEY_RIGHT);
KeyBindingManager.getKeyBindingManager().add("lastPdfPage", KeyInput.KEY_LEFT);
}
public static void main(String[] args)
{
VerifyMemoryLeakScaleImage app = new VerifyMemoryLeakScaleImage();
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
}