StackOverflowError in toString() of JSONObject

Hello,

Sometimes, I get the following error when executing the method toString() of a JSONObject.
In order to investigate the problem, I reduced the Java heap size from 22000 to 20000, but this problem didn’t occur more often. I guess this size if enough.
I also increase the “Maximum size of thread stack (in blocks)” from 4 to 5, and the problem happens again. But I don’t know the meaning of this.
Also, I don’t know what means “Number of blocks in pool”. (currently 13).
The exception occurs at the line 1118 in JSONObject.class :slight_smile:
" StringBuffer sb = new StringBuffer("{");"

Exception in thread “slowRequestsThread” java.lang.StackOverflowError: EDC-1.2:E=-1
at com.is2t.tools.ArrayTools.@M:0x3f4e4f6c:0x3f4e4f84@
at java.lang.AbstractStringBuilder.@M:0x3f4ea250:0x3f4ea266@
at java.lang.AbstractStringBuilder.@M:0x3f4eb72c:0x3f4eb752@
at java.lang.StringBuffer.@M:0x3f4ea72c:0x3f4ea74e@
at org.json.me.JSONObject.@M:0x3f4ea004:0x3f4ea030@
at org.json.me.JSONObject.@M:0x3f4e4cc4:0x3f4e4dd0@
at org.json.me.JSONArray.@M:0x3f4ce108:0x3f4ce148@
at org.json.me.JSONArray.@M:0x3f4d5564:0x3f4d5596@
at org.json.me.JSONObject.@M:0x3f4e4cc4:0x3f4e4dd0@
at org.json.me.JSONObject.@M:0x3f4ea004:0x3f4ea08e@
at org.json.me.JSONObject.@M:0x3f4e4cc4:0x3f4e4dd0@
at org.json.me.JSONArray.@M:0x3f4ce108:0x3f4ce148@
at org.json.me.JSONArray.@M:0x3f4d5564:0x3f4d5596@
at org.json.me.JSONObject.@M:0x3f4e4cc4:0x3f4e4dd0@
at org.json.me.JSONObject.@M:0x3f4ea004:0x3f4ea08e@
at org.json.me.JSONObject.@M:0x3f4e4cc4:0x3f4e4dd0@
at org.json.me.JSONArray.@M:0x3f4ce108:0x3f4ce148@
at org.json.me.JSONArray.@M:0x3f4d5564:0x3f4d5596@
at org.json.me.JSONObject.@M:0x3f4e4cc4:0x3f4e4dd0@
at org.json.me.JSONObject.@M:0x3f4ea004:0x3f4ea08e@
at org.json.me.JSONObject.@M:0x3f4e4cc4:0x3f4e4dd0@
at org.json.me.JSONObject.@M:0x3f4ea004:0x3f4ea08e@
at com.otodo.hub.impl.request.RequestManagerImpl.@M:0x3f4e0124:0x3f4e0140@
at com.otodo.hub.impl.request.RequestManagerImpl.@M:0x3f4e5404:0x3f4e54c0@
at com.otodo.hub.impl.request.Request.@M:0x3f4c1a98:0x3f4c1aba@
at com.otodo.hub.impl.request.PairByAction.@M:0x3f4c18f0:0x3f4c19ae@
at com.otodo.hub.impl.request.PairByAction.@M:0x3f4c74ac:0x3f4c74c6@
at com.otodo.hub.impl.request.PairingRequest.@M:0x3f4c7350:0x3f4c7457@
at com.otodo.hub.impl.request.Request.@M:0x3f4e92ac:0x3f4e92b8@
at com.otodo.hub.impl.request.RequestManagerImpl$2.@M:0x3f4c1a88:0x3f4c1a96@
at java.lang.Thread.@M:0x3f4ee9f0:0x3f4eea08@
at java.lang.Thread.@M:0x3f4ee93c:0x3f4ee948@
at java.lang.Thread.@M:0x3f4ee9a8:0x3f4ee9b3@

Best regards

Hello Benoit,

The stack overflow occurs when a thread stacks overpass the limitation. A function’s stack increase when going deeper in call (typically recursive calls), with functions parameters and local variables.

As you said the stack limitations are defined with two main parameters:

  • Maximum size of thread stack (in blocks): this is a max number of block that one stack can take
  • Number of blocks in pool: this is the total number of block that all the stacks will share

A quick solution, if you have enough memory will be to increase both the pool of blocks and max per stack.

As your SOE occurs when parsing a JSONObject, is your json big? Could you handle your json with streams (ej.library.iot.json#1.0.0)

Regards,

A StackOverflowError is simply signals that there is no more memory available. It is to the stack what an OutOfMemoryError is to the heap: it simply signals that there is no more memory available. JVM has a given memory allocated for each stack of each thread, and if an attempt to call a method happens to fill this memory, JVM throws an error. Just like it would do if you were trying to write at index N of an array of length N. No memory corruption can happen. The stack can not write into the heap.

The common cause for a stackoverflow is a bad recursive call. Typically, this is caused when your recursive functions doesn’t have the correct termination condition, so it ends up calling itself forever. Or when the termination condition is fine, it can be caused by requiring too many recursive calls before fulfilling it.

Here’s an example:

public class Overflow {
    public static final void main(String[] args) {
        main(args);
    }
}

That function calls itself repeatedly with no termination condition. Consequently, the stack fills up because each call has to push a return address on the stack, but the return addresses are never popped off the stack because the function never returns, it just keeps calling itself.