Company recently bought a set of old code, nested exception occurred in the test environment deployment time is Java. Lang. StackOverflowError abnormalities, saw this exception first thought is a stack of memory, online solution is given and the stack memory size. Take the opportunity to also learn what a Java virtual machine stack is.

Java virtual machine stack

To solve StackOverflowError, we need to understand its inner workings. First we need to understand what the Java virtual machine stack is. Before we look at the Java virtual machine stack, let’s look at a bit of code.

public class TestStack {

    public static void main(String[] args) {
        a();
    }

    public static void a(){
        int a = 10;
        b();
    }

    public static void b(){ int b = 10; }}Copy the code

The code above is very simple, the overall flow is

  1. The main() method is executed first
  2. Executes the a() method called by the main() method and assigns a=10
  3. Executes the b() method called by a() and assigns b=10

Now let’s understand the action flow of the stack in the case of the above simple flow. First of all, we need to know that the stack is unique to each thread, and the one stored in the stack is called stack frame. Every time a method is entered, a stack frame will be added to the stack, that is, the yellow box below is the stack frame. Each stack frame stores local variables (e.g. Int A =10, a value is stored in local variables), operand stack, dynamic link, method exit, etc.

The local variable table stores basic data types known at compile time (Boolean, byte, CHAR, short, int, float, double, long), and object references (which refer to the addresses of instance objects stored in the heap).

When each method completes execution, the stack frame is ejected from the stack.

What causes StackOverflowError

Each thread has its own stack space, which is occupied by private variables, object addresses, and return values. If the thread stack size exceeds the specified size, StackOverflowError will be raised. For example, I changed the above code slightly

public class TestStack {

    public static void main(String[] args) {
        a();
    }

    public static void a(){
        b();
    }

    public static void b(){ a(); }}Copy the code

Let it loop and set the stack size of each thread to 160KXss160k. StackOverflowError will be raised when the stack reaches its maximum value

How to resolve StackOverflowError

Back to where we started, we need to know whether StackOverflowError was caused by a code problem or a small stack. After investigation, it was found that a piece of code for verifying information used the chain of responsibility design pattern, and the reference chain was set up in XML for more than 50 times. So a StackOverflowError can occur if the stack size is not large enough during initialization.

JAVA_OPTS=”$javA_opts-xSS500K “; JAVA_OPTS=”$javA_opts-xSS500K “; JAVA_OPTS=”$javA_opts-xSS500K “; A StackOverflowError was found when the StackOverflowError was set.

Then after ps – ef | grep tomcat check found set the stack size effect. In the Tomcat directory, grep -r “Xss” * to see where the stack size is configured, and find that the JVM information is configured in the setenv.sh file. In the setenv.sh file, CATALINA_OPTS=”$CATALINA_opts-xSS256K “is configured.

The configuration is just the environment variable that Tomcat uses, using CATALINA_OPTS, whereas if you configure the environment variable that other Java applications also use, such as JBoss, set it in JAVA_OPTS

The same configuration information appears in the configuration file. For example,

CATALINA_OPTS="$CATALINA_OPTS -Xss300k"
JAVA_OPTS="$JAVA_OPTS -Xss200k"
Copy the code

If JAVA_OPTS is at the end, it is the same as CATALINA_OPTS, if both

CATALINA_OPTS="$CATALINA_OPTS -Xss300k"
CATALINA_OPTS ="$CATALINA_OPTS -Xss200k"
Copy the code

The configuration that appears later takes effect in the order in which it appears. The problem is then solved by increasing the stack size in the setenv.sh file.