[SOLVED] I removed everything in switching between App states but memory size does not change

I try to switch between the main menu and game AppState. but does not decrease the memory of the application. for the second time switch from the main menu to the game need a double volume of memory, it stoped and throws out of memory exception.

in the app state detach method of game AppState I did:
I removed all children from the root node and GuiNode.
I called ArrayList.clear() for every list I used to keep Nodes.
I called System.gc().
I called AssetsManager.clearCache() too.

how can I solve it?

best regards.

edited:
I tried app.getRenderer().cleanup() too but nothing changed.

2 Likes

Have you checked what you have in the memory? Profile the memory use. That will give you a hint why, it seems, objects aren’t being GC’d.

You can do this with jVisualVM for example.

2 Likes

52% float
25% int

I pressed gc button of visualVm in and after game AppState but nothing changed.

1 Like

Could it be cached assets then? AssetManager has a cache. Maybe for you it should be disabled then… I think there was also this smart cache thing, that things get cleared from asset cache once they have no reference in your scene graph…? But I can’t remember what was the default.

2 Likes

I cleared assets manager cache in detaching of appstate.

1 Like

Have you removed Spatials or Objects from physics space ? because i was getting a similar problem of dropping down FPS because i removed only Spatials from rootNode without removing them from physics space

2 Likes

I didn’t use physics.

2 Likes

Cleared Mappings ?

1 Like

A good heap debugger will show you what’s still hanging around and why… you should be able to trace things back through the objects that are holding onto it.

4 Likes

profiling at the project class level was not helpful. because the biggest size and live object were 148,000B and if I select all classes as a profile option, the result is something like this:

I think the problem is not in my code. when a node is detached from the scene nothing must be there in heap too (I mean it must at list null everything depends on that Node and wait for GC) but is it.

1 Like

A heap debugger should allow you to see where things were allocated.

I cycle many millions and millions of objects through my scene graph without growing the heap. So either way, it can’t be related to the scene graph itself.

The problem is probably in your code because others don’t seem to have this issue. Also, that’s a LOT of float[] and int[] arrays… which JME doesn’t really use for anything that it holds onto. The float[] arrays are especially suspicious.

Anyway, you need to figure out how to view the heap in such a way that you can see where things were allocated or what they are referenced by. It may be that you have to take a heap snapshot. (I haven’t run a profiler in 6-7 years so I don’t remember exactly.)

2 Likes

I used aprof.jar as a java agent argument in JVM params, and this is the result:

byte[]: 3,492,414,304 (25.32%) bytes in 21,661,564 (9.72%) objects (avg size 161 bytes)
	java.util.Arrays.copyOf: 2,245,535,080 (16.28%) bytes in 222,577 (0.09%) objects (avg size 10,089 bytes)
		java.io.ByteArrayOutputStream.write: 1,691,088,672 (12.26%) bytes in 27,631 (0.01%) objects (avg size 61,203 bytes)
			com.jme3.export.binary.BinaryImporter.load: 1,630,694,360 (11.82%) bytes in 1,213 (0.00%) objects (avg size 1,344,348 bytes)
			com.jme3.audio.plugins.OGGLoader.readToBuffer: 42,851,552 (0.31%) bytes in 398 (0.00%) objects (avg size 107,667 bytes)
			de.jarnbjo.ogg.LogicalOggStreamImpl.getNextOggPacket: 9,109,064 (0.06%) bytes in 25,946 (0.01%) objects (avg size 351 bytes)
			org.recast4j.detour.io.IOUtils.toByteBuffer: 8,380,736 (0.06%) bytes in 20 (0.00%) objects (avg size 419,037 bytes)
			... 5 more below threshold: 52,960 (0.00%) bytes in 54 (0.00%) objects (avg size 981 bytes)
		java.io.ByteArrayOutputStream.toByteArray: 519,129,712 (3.76%) bytes in 18,695 (0.00%) objects (avg size 27,768 bytes)
			com.jme3.export.binary.BinaryImporter.load: 494,929,432 (3.58%) bytes in 175 (0.00%) objects (avg size 2,828,168 bytes)
			com.jme3.audio.plugins.OGGLoader.readToBuffer: 15,438,912 (0.11%) bytes in 36 (0.00%) objects (avg size 428,859 bytes)
			de.jarnbjo.ogg.LogicalOggStreamImpl.getNextOggPacket: 4,870,968 (0.03%) bytes in 18,462 (0.00%) objects (avg size 264 bytes)
			org.recast4j.detour.io.IOUtils.toByteBuffer: 3,865,048 (0.02%) bytes in 2 (0.00%) objects (avg size 1,932,524 bytes)
			... 4 more below threshold: 25,352 (0.00%) bytes in 20 (0.00%) objects (avg size 1,268 bytes)
		sun.misc.Resource.getBytes: 20,753,928 (0.15%) bytes in 4,032 (0.00%) objects (avg size 5,147 bytes)
		java.util.zip.ZipCoder.getBytes: 6,418,176 (0.04%) bytes in 101,322 (0.04%) objects (avg size 63 bytes)
		com.devexperts.aprof.transformer.AProfTransformer.transform: 3,175,280 (0.02%) bytes in 43,342 (0.01%) objects (avg size 73 bytes)
		java.lang.Class.forName: 1,923,808 (0.01%) bytes in 11,386 (0.00%) objects (avg size 169 bytes)
			com.jme3.asset.AssetConfig.acquireClass: 557,160 (0.00%) bytes in 294 (0.00%) objects (avg size 1,895 bytes)
			... 15 more below threshold: 1,366,648 (0.00%) bytes in 11,092 (0.00%) objects (avg size 123 bytes)
		java.lang.Class.newInstance: 1,583,344 (0.01%) bytes in 2,214 (0.00%) objects (avg size 715 bytes)
			java.lang.Class.newInstance: 1,506,704 (0.01%) bytes in 2,138 (0.00%) objects (avg size 705 bytes)
			... 4 more below threshold: 76,640 (0.00%) bytes in 76 (0.00%) objects (avg size 1,008 bytes)
		... 18 more below threshold: 1,462,160 (0.01%) bytes in 13,955 (0.00%) objects (avg size 105 bytes)
	sun.awt.image.ByteInterleavedRaster.getByteData: 287,833,448 (2.08%) bytes in 171,747 (0.07%) objects (avg size 1,676 bytes)
		<unknown>: 287,830,888 (2.08%) bytes in 171,715 (0.07%) objects (avg size 1,676 bytes)
		java.lang.reflect.Constructor.newInstance: 2,560 (0.00%) bytes in 32 (0.00%) objects (avg size 80 bytes)
			org.codehaus.groovy.reflection.CachedConstructor.invoke: 2,560 (0.00%) bytes in 32 (0.00%) objects (avg size 80 bytes)
	com.jme3.export.binary.ByteUtils.rightAlignBytes: 229,883,616 (1.66%) bytes in 9,578,484 (4.30%) objects (avg size 24 bytes)
	java.awt.image.DataBufferByte.<init>: 225,214,048 (1.63%) bytes in 806 (0.00%) objects (avg size 279,422 bytes)
		<unknown>: 225,211,808 (1.63%) bytes in 802 (0.00%) objects (avg size 280,813 bytes)
		java.lang.reflect.Constructor.newInstance: 2,240 (0.00%) bytes in 4 (0.00%) objects (avg size 560 bytes)
			org.codehaus.groovy.reflection.CachedConstructor.invoke: 2,240 (0.00%) bytes in 4 (0.00%) objects (avg size 560 bytes)
	com.jme3.export.binary.BinaryInputCapsule.inflateFrom: 211,592,432 (1.53%) bytes in 9,578,485 (4.30%) objects (avg size 22 bytes)
	org.objectweb.asm.ByteVector.a: 63,884,000 (0.46%) bytes in 75,495 (0.03%) objects (avg size 846 bytes)
		com.devexperts.aprof.transformer.AProfTransformer.transform: 63,884,000 (0.46%) bytes in 75,495 (0.03%) objects (avg size 846 bytes)
	org.objectweb.asm.ByteVector.<init>: 41,523,816 (0.30%) bytes in 161,776 (0.07%) objects (avg size 257 bytes)
		com.devexperts.aprof.transformer.AProfTransformer.transform: 41,523,816 (0.30%) bytes in 161,776 (0.07%) objects (avg size 257 bytes)
	javax.imageio.stream.MemoryCache.loadFromStream: 40,728,096 (0.29%) bytes in 4,962 (0.00%) objects (avg size 8,208 bytes)
		<unknown>: 40,711,680 (0.29%) bytes in 4,960 (0.00%) objects (avg size 8,208 bytes)
		java.lang.reflect.Constructor.newInstance: 16,416 (0.00%) bytes in 2 (0.00%) objects (avg size 8,208 bytes)
			org.codehaus.groovy.reflection.CachedConstructor.invoke: 16,416 (0.00%) bytes in 2 (0.00%) objects (avg size 8,208 bytes)
	com.jme3.texture.plugins.TGALoader.load: 26,984,832 (0.19%) bytes in 24 (0.00%) objects (avg size 1,124,368 bytes)
	java.util.zip.ZipCoder.getBytes: 25,376,488 (0.18%) bytes in 158,964 (0.07%) objects (avg size 160 bytes)
		<unknown>: 15,321,176 (0.11%) bytes in 101,322 (0.04%) objects (avg size 151 bytes)
		com.devexperts.aprof.transformer.AProfTransformer.transform: 7,404,000 (0.05%) bytes in 41,869 (0.01%) objects (avg size 177 bytes)
		java.lang.Class.forName: 1,823,760 (0.01%) bytes in 10,690 (0.00%) objects (avg size 171 bytes)
			com.sun.beans.finder.ClassFinder.findClass: 1,076,488 (0.00%) bytes in 6,938 (0.00%) objects (avg size 155 bytes)
			... 15 more below threshold: 747,272 (0.00%) bytes in 3,752 (0.00%) objects (avg size 199 bytes)
		... 13 more below threshold: 827,552 (0.00%) bytes in 5,083 (0.00%) objects (avg size 163 bytes)
	com.jme3.export.binary.ByteUtils.readInt: 16,462,872 (0.11%) bytes in 685,953 (0.30%) objects (avg size 24 bytes)
	java.awt.color.ICC_Profile.getData: 12,243,040 (0.08%) bytes in 76,899 (0.03%) objects (avg size 159 bytes)
	sun.awt.image.ByteInterleavedRaster.getDataElements: 10,837,296 (0.07%) bytes in 451,554 (0.20%) objects (avg size 24 bytes)
	java.util.zip.InflaterInputStream.<init>: 8,755,280 (0.06%) bytes in 6,135 (0.00%) objects (avg size 1,427 bytes)
		<unknown>: 6,889,016 (0.04%) bytes in 4,917 (0.00%) objects (avg size 1,401 bytes)
		... 14 more below threshold: 1,866,264 (0.01%) bytes in 1,218 (0.00%) objects (avg size 1,532 bytes)
	com.jme3.export.binary.BinaryImporter.readString: 8,538,928 (0.06%) bytes in 350,642 (0.15%) objects (avg size 24 bytes)
	java.io.BufferedInputStream.<init>: 8,454,240 (0.06%) bytes in 1,030 (0.00%) objects (avg size 8,208 bytes)
		<unknown>: 8,339,328 (0.06%) bytes in 1,016 (0.00%) objects (avg size 8,208 bytes)
		... 4 more below threshold: 114,912 (0.00%) bytes in 14 (0.00%) objects (avg size 8,208 bytes)
	javax.imageio.stream.ImageInputStreamImpl.<init>: 5,909,760 (0.04%) bytes in 720 (0.00%) objects (avg size 8,208 bytes)
		<unknown>: 5,876,928 (0.04%) bytes in 716 (0.00%) objects (avg size 8,208 bytes)
		java.lang.reflect.Constructor.newInstance: 32,832 (0.00%) bytes in 4 (0.00%) objects (avg size 8,208 bytes)
			org.codehaus.groovy.reflection.CachedConstructor.invoke: 32,832 (0.00%) bytes in 4 (0.00%) objects (avg size 8,208 bytes)
	de.jarnbjo.ogg.OggPage.create: 5,084,288 (0.03%) bytes in 4,320 (0.00%) objects (avg size 1,177 bytes)
	java.io.ByteArrayOutputStream.<init>: 3,549,992 (0.02%) bytes in 18,781 (0.00%) objects (avg size 189 bytes)
		<unknown>: 2,660,168 (0.01%) bytes in 243 (0.00%) objects (avg size 10,947 bytes)
		... 4 more below threshold: 889,824 (0.00%) bytes in 18,538 (0.00%) objects (avg size 48 bytes)
	org.objectweb.asm.ClassReader.a: 2,594,616 (0.01%) bytes in 612 (0.00%) objects (avg size 4,240 bytes)
		com.devexperts.aprof.transformer.AProfTransformer.transform: 2,594,616 (0.01%) bytes in 612 (0.00%) objects (avg size 4,240 bytes)
	java.lang.StringCoding$StringEncoder.encode: 2,271,488 (0.01%) bytes in 10,648 (0.00%) objects (avg size 213 bytes)
		java.lang.String.getBytes: 1,611,136 (0.01%) bytes in 8,611 (0.00%) objects (avg size 187 bytes)
			<unknown>: 1,529,768 (0.01%) bytes in 5,274 (0.00%) objects (avg size 290 bytes)
			... 9 more below threshold: 81,368 (0.00%) bytes in 3,337 (0.00%) objects (avg size 24 bytes)
		... 7 more below threshold: 660,352 (0.00%) bytes in 2,037 (0.00%) objects (avg size 324 bytes)
	com.jme3.font.BitmapTextPage.<init>: 1,196,496 (0.00%) bytes in 49,854 (0.02%) objects (avg size 24 bytes)
	com.jme3.export.binary.BinaryInputCapsule.readString: 898,976 (0.00%) bytes in 30,327 (0.01%) objects (avg size 30 bytes)
	... 73 more below threshold: 7,061,176 (0.05%) bytes in 20,769 (0.00%) objects (avg size 340 bytes)

float[]: 1,936,129,760 (14.03%) bytes in 4,500,734 (2.02%) objects (avg size 430 bytes)
	com.jme3.util.clone.Cloner.arrayClone: 1,222,467,672 (8.86%) bytes in 3,138,184 (1.40%) objects (avg size 390 bytes)
	com.jme3.collision.bih.BIHTree.initTriList: 354,617,312 (2.57%) bytes in 3,905 (0.00%) objects (avg size 90,811 bytes)
	de.jarnbjo.vorbis.Floor1.computeFloor: 188,133,568 (1.36%) bytes in 35,980 (0.01%) objects (avg size 5,229 bytes)
	com.jme3.export.binary.BinaryInputCapsule.readFloatArray: 97,846,688 (0.70%) bytes in 150,297 (0.06%) objects (avg size 651 bytes)
	com.jme3.terrain.geomipmap.TerrainQuad.createHeightSubBlock: 26,329,056 (0.19%) bytes in 5,460 (0.00%) objects (avg size 4,822 bytes)
	com.jme3.light.LightList.doubleSize: 9,375,904 (0.06%) bytes in 203,824 (0.09%) objects (avg size 46 bytes)
	org.recast4j.detour.NavMeshQuery.getPortalPoints: 5,020,032 (0.03%) bytes in 156,876 (0.07%) objects (avg size 32 bytes)
	com.jme3.light.LightList.<init>: 4,278,648 (0.03%) bytes in 178,277 (0.08%) objects (avg size 24 bytes)
		<unknown>: 4,224,504 (0.03%) bytes in 176,021 (0.07%) objects (avg size 24 bytes)
		java.lang.Class.newInstance: 54,048 (0.00%) bytes in 2,252 (0.00%) objects (avg size 24 bytes)
			com.jme3.export.SavableClassUtil.fromName: 53,952 (0.00%) bytes in 2,248 (0.00%) objects (avg size 24 bytes)
			java.lang.Class.newInstance: 96 (0.00%) bytes in 4 (0.00%) objects (avg size 24 bytes)
		java.lang.reflect.Constructor.newInstance: 96 (0.00%) bytes in 4 (0.00%) objects (avg size 24 bytes)
			org.codehaus.groovy.reflection.CachedConstructor.invoke: 96 (0.00%) bytes in 4 (0.00%) objects (avg size 24 bytes)
	com.jme3.terrain.heightmap.ImageBasedHeightMap.load: 4,194,320 (0.03%) bytes in 1 (0.00%) objects (avg size 4,194,320 bytes)
	com.jme3.font.BitmapTextPage.<init>: 3,589,488 (0.02%) bytes in 99,708 (0.04%) objects (avg size 36 bytes)
	org.recast4j.detour.NavMesh.closestPointOnDetailEdges: 3,189,696 (0.02%) bytes in 99,678 (0.04%) objects (avg size 32 bytes)
	org.recast4j.detour.Node.<init>: 2,128,544 (0.01%) bytes in 66,517 (0.02%) objects (avg size 32 bytes)
	de.jarnbjo.vorbis.MdctFloat.<init>: 2,128,000 (0.01%) bytes in 456 (0.00%) objects (avg size 4,667 bytes)
	org.recast4j.detour.NavMeshQuery.getEdgeMidPoint: 2,123,168 (0.01%) bytes in 66,349 (0.02%) objects (avg size 32 bytes)
	org.recast4j.detour.NavMesh.getPolyHeight: 1,891,360 (0.01%) bytes in 34,034 (0.01%) objects (avg size 56 bytes)
	com.jme3.collision.bih.BIHNode.intersectWhere: 1,871,424 (0.01%) bytes in 58,482 (0.02%) objects (avg size 32 bytes)
	org.recast4j.detour.DetourCommon.vSub: 1,100,864 (0.00%) bytes in 34,402 (0.01%) objects (avg size 32 bytes)
	org.recast4j.detour.NavMesh.closestPointOnPoly: 1,069,696 (0.00%) bytes in 33,428 (0.01%) objects (avg size 32 bytes)
	org.recast4j.detour.DetourCommon.vLerp: 1,068,064 (0.00%) bytes in 33,377 (0.01%) objects (avg size 32 bytes)
	com.simsilica.lemur.geom.TbtQuad.clone: 1,047,536 (0.00%) bytes in 37,412 (0.01%) objects (avg size 28 bytes)
	... 46 more below threshold: 2,658,720 (0.01%) bytes in 64,087 (0.02%) objects (avg size 41 bytes)

someone can tell me where is the problem?

1 Like

This seems to be showing what created the objects. It’s only semi-useful.

What you really need to find is what’s still holding active references to these objects.

2 Likes

You’re using VisualVM, which has some tools that may help.

First, you need to take a Heap Dump (From the Monitor tab) rather than just looking at the live sampling.

When your heap dump is loaded, you’ll want to change the following settings:

  1. Change from summary to Objects (Red)
  2. Sort by Retained Size (Green) VisualVM will ask if it should calculate retained sizes, which may take a few minutes. At this point, your culprit may already be floating to the top.
  3. Shift to looking at specific instances rather than classes. (Blue)
  4. Probably want to look at dominators (Yellow) This is specifically calling out objects that are a bottleneck to releasing large amounts of memory.
  5. At this point, if you are forgetting to null out references at a very specific place or places (Seems likely) Your problem objects should be right at the top of the list.
  6. If you can’t tell where a specific object is being referenced, activate the GC Root display. (Purple) Select an object in the list, and the lower pane will show you where it is referenced from.

NOTE: I didn’t have a good example of a misbehaving application to play with, so my screenshot is of VisualVM profiling itself. It seems to be a fairly well behaved application, memory-wise. The sort of issue that you are describing is almost certain to show a single object or two that are very obviously retaining a much larger share of the memory than the rest of the program.

9 Likes

thank you so much, finally, I found the memory leaks in my code using VisualVm in that way.

3 Likes