How to debug OutOfMemoryError

Hello,

I have recently updated my MicroEJ platform to add the network support.
I have tested this with a simple application that just do a DNS request and it works fine, but when I wanted to try it with my main application I got an OutOfMemoryError:

Exception in thread “main” java.lang.OutOfMemoryError
at ej.bon.Immortals.@M:0x808b138:0x808b148@
at ej.sni.PoolOfImmortalByteBuffers.@M:0x8085678:0x8085692@
at ej.sni.PoolOfReusableResources.@M:0x808acd4:0x808ad20@
at ej.sni.PoolOfLimitedReusableResources.@M:0x8085698:0x80856ce@
at ej.sni.PoolOfImmortalByteBuffers.@M:0x808aef0:0x808af04@
at com.is2t.support.net.NetworkResources.@M:0x809486c:0x8094892@
at com.is2t.support.net.NetworkResources.@M:0x80b7824:0x80b783c@
at java.lang.Thread.@M:0x80b60e0:0x80b60f0@
at java.lang.Thread.@M:0x80c0190:0x80c01a4@
at java.lang.Thread.@M:0x80c015c:0x80c0167@
VM END (exit code = 0)

I don’t really know how to debug this and why i need more memory. I also don’t know where to declare this extract memory.
Do you have some documentation or flow that could help me to debug this type of error?

Thanks for your help.

A.W.

Hello,

Can you please provide the decoded stack trace using Stack Trace Reader ?

https://docs.microej.com/en/latest/ApplicationDeveloperGuide/stackTraceReader.html

Thanks,

–Frédéric

Hi Fréderic,
Thanks for the hint, I have missed this stackTraceReader while reading the documentation.
Here is the trace decoded:

Exception in thread “main” java.lang.OutOfMemoryError
at ej.bon.Immortals.setImmortal(Unknown Source)
at ej.sni.PoolOfImmortalByteBuffers.newResource(PoolOfImmortalByteBuffers.java:25)
at ej.sni.PoolOfReusableResources.reserve(PoolOfReusableResources.java:62)
at ej.sni.PoolOfLimitedReusableResources.(PoolOfLimitedReusableResources.java:29)
at ej.sni.PoolOfImmortalByteBuffers.(PoolOfImmortalByteBuffers.java:21)
at com.is2t.support.net.NetworkResources.initialize(NetworkResources.java:88)
at com.is2t.support.net.NetworkResources.(NetworkResources.java:84)
at java.lang.Thread.execClinit(Unknown Source)
at java.lang.Thread.clinitWrapper(Thread.java:483)
at java.lang.Thread.callWrapper(Thread.java:449)
VM END (exit code = 0)

Thanks
A. W.

Accodring to the BON setImmortal documentation (Immortals), an OutOfMemoryError is thrown when the immortals heap is full.

You can update your immortals heap size using the Application Option: core.memory.immortal.size.

Ok, indeed this fixed the issue.
I update core.memory.immortal.size from 256 to over 35000.
Is there a way to print the size of the immortal heap during the application execution. I would like to size this heap as short as possible.

Thanks for your efficient help!
A.W.

Yes, you can retrieve the immortal heap usage by calling Immortals.freeMemory() right after a call to System.gc().

Here is a typical example of code:

		System.gc();
		long used = Immortals.totalMemory() - Immortals.freeMemory();
		System.out.println("Current Immortal Heap Usage = " + used + " (bytes)");

–Frédéric

Thanks Frederic,
That’s what I need.

Regards

A.W.