Author Topic: OutOfMemoryError on ICS  (Read 4045 times)

Offline Thomas.

  • double
  • *****
  • Posts: 833
    • View Profile
OutOfMemoryError on ICS
« on: November 30, 2011, 11:16:57 am »
Application crashes during the loading with this error log. On gingerbread without any problem.

Code: [Select]
11-30 11:09:33.691: W/dalvikvm(21679): threadid=14: thread exiting with uncaught exception (group=0x40a321f8)
11-30 11:09:33.695: E/AndroidRuntime(21679): FATAL EXCEPTION: Thread-7392
11-30 11:09:33.695: E/AndroidRuntime(21679): java.lang.OutOfMemoryError
11-30 11:09:33.695: E/AndroidRuntime(21679): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-30 11:09:33.695: E/AndroidRuntime(21679): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
11-30 11:09:33.695: E/AndroidRuntime(21679): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:549)
11-30 11:09:33.695: E/AndroidRuntime(21679): at com.threed.jpct.util.BitmapHelper.loadImage(BitmapHelper.java:32)
11-30 11:09:33.695: E/AndroidRuntime(21679): at com.threed.jpct.Texture.loadTexture(Texture.java:715)
11-30 11:09:33.695: E/AndroidRuntime(21679): at com.threed.jpct.Texture.loadTexture(Texture.java:703)
11-30 11:09:33.695: E/AndroidRuntime(21679): at com.threed.jpct.Texture.<init>(Texture.java:135)
11-30 11:09:33.695: E/AndroidRuntime(21679): at cz.game.util.ObjectLoader.loadValuesOfObjects(ObjectLoader.java:471)
11-30 11:09:33.695: E/AndroidRuntime(21679): at cz.game.util.ObjectLoader.loadLevel(ObjectLoader.java:314)
11-30 11:09:33.695: E/AndroidRuntime(21679): at cz.game.util.ObjectLoader.load(ObjectLoader.java:203)
11-30 11:09:33.695: E/AndroidRuntime(21679): at cz.game.util.ObjectLoader.run(ObjectLoader.java:116)
11-30 11:09:33.703: W/ActivityManager(188):   Force finishing activity com.main/cz.game.main.Demo

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: OutOfMemoryError on ICS
« Reply #1 on: November 30, 2011, 11:21:38 am »
No idea. I'm not doing anything OS related anywhere in the code. Maybe this relates to this: http://www.jpct.net/forum2/index.php/topic,2429.0.html?

Edit: What's the default VM memory size on that device? Maybe it's lower than on the Gingerbread device...

Offline K24A3

  • long
  • ***
  • Posts: 231
    • View Profile
Re: OutOfMemoryError on ICS
« Reply #2 on: November 30, 2011, 11:48:52 am »
I have the same problem with Honeycomb. For some reason the app uses double the RAM compared to Gingerbread. You can use the new LargeHeap parameter in Android.Manifest to increase the RAM to 256MB but you will lose Gingerbread compatibility.

Use this function to see how much RAM is used in both gingerbread and ICS:

Code: [Select]
public void logMem() {
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(0);
        df.setMinimumFractionDigits(0);

        String sTemp = "RAM allocated: " + df.format(new Double(Runtime.getRuntime().totalMemory()/1048576)) + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576)) +"MB free)";
        Log.v(TAG, sTemp);
    }

Offline Thomas.

  • double
  • *****
  • Posts: 833
    • View Profile
Re: OutOfMemoryError on ICS
« Reply #3 on: November 30, 2011, 12:37:48 pm »
I think that on gingerbread was VM memory size 48Mb and now on ICS it is 32Mb... how can I reduce demands on this memory?
K24A3:
Code: [Select]
11-30 12:24:57.277: I/jPCT-AE(22387): RAM allocated: 31MB of 32MB (0MB free)
11-30 12:24:57.414: I/dalvikvm-heap(22387): Clamp target GC heap from 32.692MB to 32.000MB
11-30 12:24:57.605: E/AndroidRuntime(22387): FATAL EXCEPTION: GLThread 7473
...

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: OutOfMemoryError on ICS
« Reply #4 on: November 30, 2011, 01:05:37 pm »

Offline K24A3

  • long
  • ***
  • Posts: 231
    • View Profile
Re: OutOfMemoryError on ICS
« Reply #5 on: December 01, 2011, 01:00:51 am »
I believe the manufacturer of the phone/tablet can set the max VM size so perhaps that is why it's only 32MB.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: OutOfMemoryError on ICS
« Reply #6 on: December 01, 2011, 06:58:21 am »
Yes, it's not an OS issue. It can be set by the manufacturer. Even 32mb is pretty much compared to others. My Nexus S has 24mb IIRC and my old Galaxy (no S) has 16.

Offline Alexey

  • int
  • **
  • Posts: 50
    • View Profile
Re: OutOfMemoryError on ICS
« Reply #7 on: December 01, 2011, 03:24:49 pm »
Not about ICS, but about memory - when i create for example 200 objects (by cloning primitive.sphere(4,1) , without any texture) i have
Code: [Select]
12-01 16:08:15.743: ERROR/dalvikvm-heap(29270): 768-byte external allocation too large for this process.
12-01 16:08:15.743: ERROR/dalvikvm(29270): Out of memory: Heap Size=23399KB, Allocated=8825KB, Bitmap Size=943KB, Limit=21884KB
12-01 16:08:15.743: ERROR/dalvikvm(29270): Trim info: Footprint=23879KB, Allowed Footprint=23879KB, Trimmed=480KB
12-01 16:08:15.743: WARN/OSMemory(29270): External allocation of 768 bytes was rejected
12-01 16:08:15.753: WARN/dalvikvm(29270): threadid=8: thread exiting with uncaught exception (group=0x40025a70)
12-01 16:08:15.773: ERROR/AndroidRuntime(29270): FATAL EXCEPTION: GLThread 9
        java.lang.OutOfMemoryError
        at org.apache.harmony.luni.platform.OSMemory.malloc(Native Method)
        at org.apache.harmony.luni.platform.PlatformAddressFactory.alloc(PlatformAddressFactory.java:150)
        at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:66)
        at java.nio.ReadWriteDirectByteBuffer.<init>(ReadWriteDirectByteBuffer.java:51)
        at java.nio.BufferFactory.newDirectByteBuffer(BufferFactory.java:93)
        at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:68)
        at com.threed.jpct.CompiledInstance.fill(CompiledInstance.java:774)
        at com.threed.jpct.Object3DCompiler.compile(Object3DCompiler.java:151)
        at com.threed.jpct.World.compile(World.java:2050)
        at com.threed.jpct.World.renderScene(World.java:1093)

Is that really out of memory or i have some memory leak ? (desire hd)

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: OutOfMemoryError on ICS
« Reply #8 on: December 01, 2011, 04:45:52 pm »
I don't know if you have a memory leak, but it might very well be an OOM. Unless you are sharing Mesh and compiled data, each instance needs it's own chunk of memory even if they are actually the same objects. Again, consider: http://www.jpct.net/wiki/index.php/Reducing_memory_usage, especially the 1.4.x parts.

Offline Alexey

  • int
  • **
  • Posts: 50
    • View Profile
Re: OutOfMemoryError on ICS
« Reply #9 on: December 01, 2011, 05:24:23 pm »
i tried cloneObject() & new Object3d(o, reuseMesh=true). Tried primitive.shareCompiledData(each cloned object).
Creation part:
Code: [Select]
Object3D original = Primitives.getSphere(4, 1);
original.compile();
original.strip();
original.build();
original.rotateY((float) (Math.PI / 4));
short i = 0;
short y = 0;
short z = 0;
short rowCount = 0;
for (int j = 0; j < particles.length; j++) {
ParticlePB particle = new ParticlePB();
Object3D o =  new Object3D(original, true);//box.cloneObject();
if (i == inRow) {
i = 0;
++rowCount;
}
original.shareCompiledData(o);
o.strip();
// o.forceGeometryIndices(true);
o.build();
y = (short) (i * moveStep);
z = (short) (rowCount * moveStep);
o.translate(0, y, z);
++i;
particle.setObject3D(o);
particles[j] = particle;
world.addObject(o);
System.out.println(usedMemory());
}
after create each SOUT write:
Code: [Select]
12-01 18:05:48.775: INFO/System.out(29877): 7857992
12-01 18:05:48.775: INFO/System.out(29877): 7870520
12-01 18:05:48.775: INFO/System.out(29877): 7885464
12-01 18:05:48.775: INFO/System.out(29877): 7898184
12-01 18:05:48.775: INFO/jPCT-AE(29877): Memory usage before compacting: 7714 KB used out of 23399 KB
So each obj ~12k, count of iteration = 500;
after that log write sequence
Code: [Select]
2-01 18:05:49.495: INFO/jPCT-AE(29877): Subobject of object 5/object7 compiled to flat fixed point data using 96 vertices in 5ms!
12-01 18:05:49.495: INFO/jPCT-AE(29877): Object 5/object7 compiled to 1 subobjects in 12ms!
12-01 18:05:49.495: INFO/jPCT-AE(29877): Object 'object7' uses one texture set!
12-01 18:05:49.495: INFO/jPCT-AE(29877): Subobject of object 6/object8 compiled to flat fixed point data using 96 vertices in 1ms!
12-01 18:05:49.505: INFO/jPCT-AE(29877): Object 6/object8 compiled to 1 subobjects in 8ms!
12-01 18:05:49.505: INFO/jPCT-AE(29877): Object 'object8' uses one texture set!
...
12-01 18:05:50.515: INFO/jPCT-AE(29877): Subobject of object 310/object312 compiled to flat fixed point data using 96 vertices in 1ms!
12-01 18:05:50.515: INFO/jPCT-AE(29877): Object 310/object312 compiled to 1 subobjects in 3ms!
12-01 18:05:50.515: INFO/jPCT-AE(29877): Object 'object312' uses one texture set!
12-01 18:05:50.515: ERROR/dalvikvm-heap(29877): 768-byte external allocation too large for this process.
12-01 18:05:50.515: ERROR/dalvikvm(29877): Out of memory: Heap Size=23399KB, Allocated=8826KB, Bitmap Size=943KB, Limit=21884KB
12-01 18:05:50.515: ERROR/dalvikvm(29877): Trim info: Footprint=23879KB, Allowed Footprint=23879KB, Trimmed=480KB
12-01 18:05:50.515: WARN/OSMemory(29877): External allocation of 768 bytes was rejected
12-01 18:05:50.525: WARN/dalvikvm(29877): threadid=8: thread exiting with uncaught exception (group=0x40025a70)
12-01 18:05:50.535: ERROR/AndroidRuntime(29877): FATAL EXCEPTION: GLThread 9
        java.lang.OutOfMemoryError
        at org.apache.harmony.luni.platform.OSMemory.malloc(Native Method)
        at org.apache.harmony.luni.platform.PlatformAddressFactory.alloc(PlatformAddressFactory.java:150)
        at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:66)
        at java.nio.ReadWriteDirectByteBuffer.<init>(ReadWriteDirectByteBuffer.java:51)
        at java.nio.BufferFactory.newDirectByteBuffer(BufferFactory.java:93)
        at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:68)
        at com.threed.jpct.CompiledInstance.fill(CompiledInstance.java:774)
        at com.threed.jpct.Object3DCompiler.compile(Object3DCompiler.java:151)
        at com.threed.jpct.World.compile(World.java:2050)
        at com.threed.jpct.World.renderScene(World.java:1093)

There are only this objects in world. I think they should not overflow the memory.
What doing when out like "INFO/jPCT-AE(29877): Subobject of object 5/object7 compiled to flat fixed point data using 96 vertices in 5ms!
12-01 18:05:49.495: INFO/jPCT-AE(29877): Object 5/object7 compiled to 1 subobjects in 12ms!" ?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: OutOfMemoryError on ICS
« Reply #10 on: December 01, 2011, 08:32:37 pm »
This

Code: [Select]
original.shareCompiledData(o);
is wrong. It has to be the other way round

Code: [Select]
o.shareCompiledData(original);
The log output that you see is when it converts the Object3Ds into native data structures, which takes some additional memory.

Offline Alexey

  • int
  • **
  • Posts: 50
    • View Profile
Re: OutOfMemoryError on ICS
« Reply #11 on: December 02, 2011, 09:55:16 am »
Code: [Select]
o.shareCompiledData(original);
Yes! Thats it! Thank you! With this data sharing i run 3000 objects  without OOM.
Another question  - if objects convert to native data (as i know, native memory usage  not included to activity memory usage) they should not contribute to the overflow activity memory limit if load its by parts then convert loaded part to native data and clear their mesh data in java object3d (of course this only for static meshes). If sometime will be need to load ~many hard-weight static objects without sharing compile data, is it possible to realize some like this loading process? Is there a way to force convert obj to native data and safety set null its mesh data? (and same for textures)

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: OutOfMemoryError on ICS
« Reply #12 on: December 02, 2011, 10:39:08 am »
Native memory counts to the VM memory as well. There are hacks around this, but not if you reserve the memory via the VM. strip() already nulls what can be nulled after uploading to the GPU. The rest of the data is needed by the engine at runtime. Concerning textures, you can disable the copy in main memory...but that will break the option to let jPCT manage context switches for you, i.e. if you pause/stop or just rotate the device, the gl context is lost and all the data has to be uploaded again. jPCT handles this for you, but if you remore the texture from main memory, this isn't possible and everything will go white instead. You can't do the conversion earlier (i.e. at load time), because it has to happen in the render thread.