Assimp memory leak

Started by Edde, September 28, 2020, 16:43:36

Previous topic - Next topic

Edde

I'm trying to load obj models using assimp but I get a memory leak

[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3EE50000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileCloseProc.<init>(AIFileCloseProc.java:51)
   at com.eldev.engine.loader.MeshLoader$2.<init>(MeshLoader.java:80)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:80)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3EE40000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileOpenProc.<init>(AIFileOpenProc.java:52)
   at com.eldev.engine.loader.MeshLoader$1.<init>(MeshLoader.java:40)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:40)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D40490000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileReadProc.<init>(AIFileReadProc.java:53)
   at com.eldev.engine.loader.MeshLoader$1$1.<init>(MeshLoader.java:50)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:50)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D404B0000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileTellProc.<init>(AIFileTellProc.java:50)
   at com.eldev.engine.loader.MeshLoader$1$3.<init>(MeshLoader.java:69)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:69)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D404A0000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileSeek.<init>(AIFileSeek.java:52)
   at com.eldev.engine.loader.MeshLoader$1$2.<init>(MeshLoader.java:57)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:57)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3F5D0000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileTellProc.<init>(AIFileTellProc.java:50)
   at com.eldev.engine.loader.MeshLoader$1$3.<init>(MeshLoader.java:69)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:69)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3F5C0000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileSeek.<init>(AIFileSeek.java:52)
   at com.eldev.engine.loader.MeshLoader$1$2.<init>(MeshLoader.java:57)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:57)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3F5B0000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileReadProc.<init>(AIFileReadProc.java:53)
   at com.eldev.engine.loader.MeshLoader$1$1.<init>(MeshLoader.java:50)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:50)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3FD40000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileTellProc.<init>(AIFileTellProc.java:50)
   at com.eldev.engine.loader.MeshLoader$1$3.<init>(MeshLoader.java:69)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:69)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3FD30000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileSeek.<init>(AIFileSeek.java:52)
   at com.eldev.engine.loader.MeshLoader$1$2.<init>(MeshLoader.java:57)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:57)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)
[LWJGL] 16 bytes leaked, thread 1 (Game Thread), address: 0x12D3FD20000
   at org.lwjgl.system.Callback.create(Callback.java:136)
   at org.lwjgl.system.Callback.<init>(Callback.java:86)
   at org.lwjgl.assimp.AIFileReadProc.<init>(AIFileReadProc.java:53)
   at com.eldev.engine.loader.MeshLoader$1$1.<init>(MeshLoader.java:50)
   at com.eldev.engine.loader.MeshLoader$1.invoke(MeshLoader.java:50)
   at org.lwjgl.assimp.AIFileOpenProcI.callback(AIFileOpenProcI.java:33)
   at org.lwjgl.system.JNI.invokePPP(Native Method)
   at org.lwjgl.assimp.Assimp.naiImportFileEx(Assimp.java:2593)
   at org.lwjgl.assimp.Assimp.aiImportFileEx(Assimp.java:2641)
   at com.eldev.engine.loader.MeshLoader.loadMesh(MeshLoader.java:86)
   at com.eldev.game.Game.main(Game.java:26)

spasi

LWJGL callback function objects must be manually freed to avoid memory leaks.

Edde

When I free the callback function objects i get an exception

Exception in thread "Render Thread" java.lang.IllegalStateException: The memory address specified is not being tracked: 0x15D01D9A4F0
	at org.lwjgl.system.MemoryManage$DebugAllocator.untrack(MemoryManage.java:259)
	at org.lwjgl.system.MemoryManage$DebugAllocator.free(MemoryManage.java:220)
	at org.lwjgl.system.MemoryUtil.nmemFree(MemoryUtil.java:336)

spasi

Which LWJGL version do you use?

Edde


spasi

I think the issue is that AIFileIO's OpenProc and CloseProc are invoked multiple times (3 in my testing) within a single aiImportFileEx call. If OpenProc creates a new AIFile each time, then you need to make sure that the corresponding CloseProc invocation is freeing those callbacks.

This is a bit wasteful of course. Depending on how your code is structured, you may be able to reuse the callback instances and avoid the overhead.

Edde


spasi

WavefrontObjDemo has been fixed to properly cleanup the AIFileIO & AIFile callbacks.