admin管理员组

文章数量:1026900

Trees are expensive to draw in OpenGL in time and space. Currently I'm experimenting with creating and drawing a grid of a few dozen trees at a time, which gets recreated regularly as the character moves to keep up. However, with each reallocation of the same tree vertice buffers, available memory drops. I've tried forcing garbage collection after each reallocation, but that just slows the leak down. Is there a way to avoid this?

Code with tracked memory.

Log.d("memorytest","maketree before TreeA usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

myglrenderer.TreeAGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeAGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeAGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree before TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));


myglrenderer.TreeBGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeBGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeBGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree after TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

Results:

----

maketree before TreeA  usedMemInMB 286 maxHeapSizeInMB 512 availHeapSizeInMB 226

maketree after TreeA usedMemInMB 335 maxHeapSizeInMB 512 availHeapSizeInMB 177

maketree after TreeB usedMemInMB 396 maxHeapSizeInMB 512 availHeapSizeInMB 116

maketree before TreeA usedMemInMB 384 maxHeapSizeInMB 512 availHeapSizeInMB 128

maketree after TreeA usedMemInMB 437 maxHeapSizeInMB 512 availHeapSizeInMB 75

maketree after TreeB  usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

 -----

maketree before TreeA usedMemInMB 429 maxHeapSizeInMB 512 availHeapSizeInMB 83

maketree after TreeA usedMemInMB 500 maxHeapSizeInMB 512 availHeapSizeInMB 12

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

 -----

outofmemoryerror

Results with garbage collection after each reallocation.

 maketree before TreeA usedMemInMB 292 maxHeapSizeInMB 512 availHeapSizeInMB 220

maketree after TreeA usedMemInMB 346 maxHeapSizeInMB 512 availHeapSizeInMB 166 

maketree after TreeB usedMemInMB 397 maxHeapSizeInMB 512 availHeapSizeInMB 115

maketree after Runtime.getRuntime().gc() usedMemInMB 376 maxHeapSizeInMB 512 availHeapSizeInMB 136

 ----

maketree before TreeA usedMemInMB 392 maxHeapSizeInMB 512 availHeapSizeInMB 120

maketree after TreeA usedMemInMB 404 maxHeapSizeInMB 512 availHeapSizeInMB 108

maketree after TreeB usedMemInMB 448 maxHeapSizeInMB 512 availHeapSizeInMB 64

maketree fter Runtime.getRuntime().gc() usedMemInMB 383 maxHeapSizeInMB 512 availHeapSizeInMB 129

 ----

maketree before TreeA usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

maketree after TreeA usedMemInMB 432 maxHeapSizeInMB 512 availHeapSizeInMB 80

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

maketree after Runtime.getRuntime().gc()  usedMemInMB 457 maxHeapSizeInMB 512 availHeapSizeInMB 55

 ----

maketree before TreeA usedMemInMB 492 maxHeapSizeInMB 512 availHeapSizeInMB 20

maketree after TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

maketree after TreeB usedMemInMB 510 maxHeapSizeInMB 512 availHeapSizeInMB 2

maketree after Runtime.getRuntime().gc() usedMemInMB 467 maxHeapSizeInMB 512 availHeapSizeInMB 45

 ----

maketree before TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

outofmemoryerror

Trees are expensive to draw in OpenGL in time and space. Currently I'm experimenting with creating and drawing a grid of a few dozen trees at a time, which gets recreated regularly as the character moves to keep up. However, with each reallocation of the same tree vertice buffers, available memory drops. I've tried forcing garbage collection after each reallocation, but that just slows the leak down. Is there a way to avoid this?

Code with tracked memory.

Log.d("memorytest","maketree before TreeA usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

myglrenderer.TreeAGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeAGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeAGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree before TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));


myglrenderer.TreeBGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeBGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeBGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree after TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

Results:

----

maketree before TreeA  usedMemInMB 286 maxHeapSizeInMB 512 availHeapSizeInMB 226

maketree after TreeA usedMemInMB 335 maxHeapSizeInMB 512 availHeapSizeInMB 177

maketree after TreeB usedMemInMB 396 maxHeapSizeInMB 512 availHeapSizeInMB 116

maketree before TreeA usedMemInMB 384 maxHeapSizeInMB 512 availHeapSizeInMB 128

maketree after TreeA usedMemInMB 437 maxHeapSizeInMB 512 availHeapSizeInMB 75

maketree after TreeB  usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

 -----

maketree before TreeA usedMemInMB 429 maxHeapSizeInMB 512 availHeapSizeInMB 83

maketree after TreeA usedMemInMB 500 maxHeapSizeInMB 512 availHeapSizeInMB 12

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

 -----

outofmemoryerror

Results with garbage collection after each reallocation.

 maketree before TreeA usedMemInMB 292 maxHeapSizeInMB 512 availHeapSizeInMB 220

maketree after TreeA usedMemInMB 346 maxHeapSizeInMB 512 availHeapSizeInMB 166 

maketree after TreeB usedMemInMB 397 maxHeapSizeInMB 512 availHeapSizeInMB 115

maketree after Runtime.getRuntime().gc() usedMemInMB 376 maxHeapSizeInMB 512 availHeapSizeInMB 136

 ----

maketree before TreeA usedMemInMB 392 maxHeapSizeInMB 512 availHeapSizeInMB 120

maketree after TreeA usedMemInMB 404 maxHeapSizeInMB 512 availHeapSizeInMB 108

maketree after TreeB usedMemInMB 448 maxHeapSizeInMB 512 availHeapSizeInMB 64

maketree fter Runtime.getRuntime().gc() usedMemInMB 383 maxHeapSizeInMB 512 availHeapSizeInMB 129

 ----

maketree before TreeA usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

maketree after TreeA usedMemInMB 432 maxHeapSizeInMB 512 availHeapSizeInMB 80

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

maketree after Runtime.getRuntime().gc()  usedMemInMB 457 maxHeapSizeInMB 512 availHeapSizeInMB 55

 ----

maketree before TreeA usedMemInMB 492 maxHeapSizeInMB 512 availHeapSizeInMB 20

maketree after TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

maketree after TreeB usedMemInMB 510 maxHeapSizeInMB 512 availHeapSizeInMB 2

maketree after Runtime.getRuntime().gc() usedMemInMB 467 maxHeapSizeInMB 512 availHeapSizeInMB 45

 ----

maketree before TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

outofmemoryerror
Share Improve this question edited yesterday Rabbid76 211k29 gold badges156 silver badges196 bronze badges asked yesterday AndroidcoderAndroidcoder 4,6595 gold badges37 silver badges51 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Garbage collection is an automatic process in java. You can request the garbage collector to run, but that isn't really recommended because it will impact performance and won't necessarily run the collector. From the java docs

Calling this method suggests that the Java virtual machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse.

The reason you are still getting an outofmemory error is that the garbage collector can only delete unreferenced objects to free up memory.

You should instead focus on helping the garbage collector finding unreferenced objects and to do that you have a few options:

  • Setting your objects to null indicates that they are ready to be collected.
  • Objects going out of scope indicate they are ready to be collected.
  • Changing static objects to non-static objects, this won't directly signal to the garbage collector that the object is ready to be collected but it is less likely that the object will persist through out the life of the application saving some resources.

There are more ways to make things eligible for garbage collection then this. Hope this helps some

Trees are expensive to draw in OpenGL in time and space. Currently I'm experimenting with creating and drawing a grid of a few dozen trees at a time, which gets recreated regularly as the character moves to keep up. However, with each reallocation of the same tree vertice buffers, available memory drops. I've tried forcing garbage collection after each reallocation, but that just slows the leak down. Is there a way to avoid this?

Code with tracked memory.

Log.d("memorytest","maketree before TreeA usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

myglrenderer.TreeAGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeAGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeAGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree before TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));


myglrenderer.TreeBGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeBGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeBGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree after TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

Results:

----

maketree before TreeA  usedMemInMB 286 maxHeapSizeInMB 512 availHeapSizeInMB 226

maketree after TreeA usedMemInMB 335 maxHeapSizeInMB 512 availHeapSizeInMB 177

maketree after TreeB usedMemInMB 396 maxHeapSizeInMB 512 availHeapSizeInMB 116

maketree before TreeA usedMemInMB 384 maxHeapSizeInMB 512 availHeapSizeInMB 128

maketree after TreeA usedMemInMB 437 maxHeapSizeInMB 512 availHeapSizeInMB 75

maketree after TreeB  usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

 -----

maketree before TreeA usedMemInMB 429 maxHeapSizeInMB 512 availHeapSizeInMB 83

maketree after TreeA usedMemInMB 500 maxHeapSizeInMB 512 availHeapSizeInMB 12

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

 -----

outofmemoryerror

Results with garbage collection after each reallocation.

 maketree before TreeA usedMemInMB 292 maxHeapSizeInMB 512 availHeapSizeInMB 220

maketree after TreeA usedMemInMB 346 maxHeapSizeInMB 512 availHeapSizeInMB 166 

maketree after TreeB usedMemInMB 397 maxHeapSizeInMB 512 availHeapSizeInMB 115

maketree after Runtime.getRuntime().gc() usedMemInMB 376 maxHeapSizeInMB 512 availHeapSizeInMB 136

 ----

maketree before TreeA usedMemInMB 392 maxHeapSizeInMB 512 availHeapSizeInMB 120

maketree after TreeA usedMemInMB 404 maxHeapSizeInMB 512 availHeapSizeInMB 108

maketree after TreeB usedMemInMB 448 maxHeapSizeInMB 512 availHeapSizeInMB 64

maketree fter Runtime.getRuntime().gc() usedMemInMB 383 maxHeapSizeInMB 512 availHeapSizeInMB 129

 ----

maketree before TreeA usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

maketree after TreeA usedMemInMB 432 maxHeapSizeInMB 512 availHeapSizeInMB 80

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

maketree after Runtime.getRuntime().gc()  usedMemInMB 457 maxHeapSizeInMB 512 availHeapSizeInMB 55

 ----

maketree before TreeA usedMemInMB 492 maxHeapSizeInMB 512 availHeapSizeInMB 20

maketree after TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

maketree after TreeB usedMemInMB 510 maxHeapSizeInMB 512 availHeapSizeInMB 2

maketree after Runtime.getRuntime().gc() usedMemInMB 467 maxHeapSizeInMB 512 availHeapSizeInMB 45

 ----

maketree before TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

outofmemoryerror

Trees are expensive to draw in OpenGL in time and space. Currently I'm experimenting with creating and drawing a grid of a few dozen trees at a time, which gets recreated regularly as the character moves to keep up. However, with each reallocation of the same tree vertice buffers, available memory drops. I've tried forcing garbage collection after each reallocation, but that just slows the leak down. Is there a way to avoid this?

Code with tracked memory.

Log.d("memorytest","maketree before TreeA usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

myglrenderer.TreeAGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeAGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeAGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeAGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree before TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));


myglrenderer.TreeBGridPositions = ByteBuffer.allocateDirect(terrain_positiondata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridPositions.put(terrain_positiondata).position(0);

myglrenderer.TreeBGridNormals = ByteBuffer.allocateDirect(terrain_normaldata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridNormals.put(terrain_normaldata).position(0);

myglrendererTreeBGridTextures = ByteBuffer.allocateDirect(terrain_texturedata.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
myglrenderer.TreeBGridTextures.put(terrain_texturedata).position(0);

Log.d("memorytest","maketree after TreeB usedMemInMB "+((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory()) / 1048576L)+
        " maxHeapSizeInMB "+(gamepanel.runtime.maxMemory() / 1048576L)+" availHeapSizeInMB "+
        ((gamepanel.runtime.maxMemory() / 1048576L)-((gamepanel.runtime.totalMemory() - gamepanel.runtime.freeMemory())/1048576L)));

Results:

----

maketree before TreeA  usedMemInMB 286 maxHeapSizeInMB 512 availHeapSizeInMB 226

maketree after TreeA usedMemInMB 335 maxHeapSizeInMB 512 availHeapSizeInMB 177

maketree after TreeB usedMemInMB 396 maxHeapSizeInMB 512 availHeapSizeInMB 116

maketree before TreeA usedMemInMB 384 maxHeapSizeInMB 512 availHeapSizeInMB 128

maketree after TreeA usedMemInMB 437 maxHeapSizeInMB 512 availHeapSizeInMB 75

maketree after TreeB  usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

 -----

maketree before TreeA usedMemInMB 429 maxHeapSizeInMB 512 availHeapSizeInMB 83

maketree after TreeA usedMemInMB 500 maxHeapSizeInMB 512 availHeapSizeInMB 12

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

 -----

outofmemoryerror

Results with garbage collection after each reallocation.

 maketree before TreeA usedMemInMB 292 maxHeapSizeInMB 512 availHeapSizeInMB 220

maketree after TreeA usedMemInMB 346 maxHeapSizeInMB 512 availHeapSizeInMB 166 

maketree after TreeB usedMemInMB 397 maxHeapSizeInMB 512 availHeapSizeInMB 115

maketree after Runtime.getRuntime().gc() usedMemInMB 376 maxHeapSizeInMB 512 availHeapSizeInMB 136

 ----

maketree before TreeA usedMemInMB 392 maxHeapSizeInMB 512 availHeapSizeInMB 120

maketree after TreeA usedMemInMB 404 maxHeapSizeInMB 512 availHeapSizeInMB 108

maketree after TreeB usedMemInMB 448 maxHeapSizeInMB 512 availHeapSizeInMB 64

maketree fter Runtime.getRuntime().gc() usedMemInMB 383 maxHeapSizeInMB 512 availHeapSizeInMB 129

 ----

maketree before TreeA usedMemInMB 433 maxHeapSizeInMB 512 availHeapSizeInMB 79

maketree after TreeA usedMemInMB 432 maxHeapSizeInMB 512 availHeapSizeInMB 80

maketree after TreeB usedMemInMB 501 maxHeapSizeInMB 512 availHeapSizeInMB 11

maketree after Runtime.getRuntime().gc()  usedMemInMB 457 maxHeapSizeInMB 512 availHeapSizeInMB 55

 ----

maketree before TreeA usedMemInMB 492 maxHeapSizeInMB 512 availHeapSizeInMB 20

maketree after TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

maketree after TreeB usedMemInMB 510 maxHeapSizeInMB 512 availHeapSizeInMB 2

maketree after Runtime.getRuntime().gc() usedMemInMB 467 maxHeapSizeInMB 512 availHeapSizeInMB 45

 ----

maketree before TreeA usedMemInMB 485 maxHeapSizeInMB 512 availHeapSizeInMB 27

outofmemoryerror
Share Improve this question edited yesterday Rabbid76 211k29 gold badges156 silver badges196 bronze badges asked yesterday AndroidcoderAndroidcoder 4,6595 gold badges37 silver badges51 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Garbage collection is an automatic process in java. You can request the garbage collector to run, but that isn't really recommended because it will impact performance and won't necessarily run the collector. From the java docs

Calling this method suggests that the Java virtual machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse.

The reason you are still getting an outofmemory error is that the garbage collector can only delete unreferenced objects to free up memory.

You should instead focus on helping the garbage collector finding unreferenced objects and to do that you have a few options:

  • Setting your objects to null indicates that they are ready to be collected.
  • Objects going out of scope indicate they are ready to be collected.
  • Changing static objects to non-static objects, this won't directly signal to the garbage collector that the object is ready to be collected but it is less likely that the object will persist through out the life of the application saving some resources.

There are more ways to make things eligible for garbage collection then this. Hope this helps some

本文标签: