How to Increase the Java Stack Size

How to increase the Java stack size?

Hmm... it works for me and with far less than 999MB of stack:

> java -Xss4m Test
0

(Windows JDK 7, build 17.0-b05 client VM, and Linux JDK 6 - same version information as you posted)

How to increase stack size to allow more recursion?

Your error is indeed a StackOverflow caused by too much recursion, but Processing covers that up with the strange error you're seeing. Documentation on that bug is here.

You can increase the Java stack size to increase the limit of recursive calls. Info can be found here, but the gist is that you have to pass the -Xss setting into Java at runtime.

However, that setting requires that you run your sketch as a Java application. This is possible, but it involves exporting your sketch as a jar, then running the jar via the command prompt, or switching to eclipse. That's a lot more work than simply hitting the run button in Processing- and any users you send your jar would have to do the same.

Instead, you should probably refactor your algorithm to eliminate the excessive recursion.

What is the default stack size, can it grow, how does it work with garbage collection?

How much a stack can grow?

You can use a VM option named ss to adjust the maximum stack size. A VM option is usually passed using -X{option}. So you can use java -Xss1M to set the maximum of stack size to 1M.

Each thread has at least one stack. Some Java Virtual Machines (JVM) put Java stack (Java method calls) and native stack (Native method calls in VM) into one stack, and perform stack unwinding using a "Managed to Native Frame", known as M2nFrame. Some JVMs keep two stacks separately. The Xss set the size of the Java Stack in most cases.

For many JVMs, they put different default values for stack size on different platforms.



Can we limit this growth?

When a method call occurs, a new stack frame will be created on the stack of that thread. The stack will contain local variables, parameters, return address, etc. In Java, you can never put an object on stack, only object reference can be stored on stack. Since array is also an object in Java, arrays are also not stored on stack. So, if you reduce the amount of your local primitive variables, parameters by grouping them into objects, you can reduce the space on stack. Actually, the fact that we cannot explicitly put objects on Java stack affects the performance some time (cache miss).



Does stack has some default minimum value or default maximum value?

As I said before, different VMs are different, and may change over versions. See here.



How does garbage collection work on stack?

Garbage collections in Java is a hot topic. Garbage collection aims to collect unreachable objects in the heap. So that needs a definition of 'reachable.' Everything on the stack constitutes part of the root set references in GC. Everything that is reachable from every stack of every thread should be considered as live. There are some other root set references, like Thread objects and some class objects.

This is only a very vague use of stack on GC. Currently most JVMs are using a generational GC. This article gives brief introduction about Java GC. And recently I read a very good article talking about the GC on .NET platform. The GC on Oracle JVM is quite similar so I think that might also help you.

What sets the stack size?

the JVM and yes you can pass parms to change the stack size. This question/answer is somewhat close to your question. How to increase the Java stack size?

How to fine tune JVM configurations to reduce the max thread stack size?

Yes, you can do that. Basically, you can configure the max Stack size of your thread in your application.

For this, you can use the option named ss to adjust the maximum stack size. A VM option is usually passed using -X{option}. So you can use java -Xss1M to set the maximum of stack size to 1M.

One more example is java -Xss1048576, this sets the max thread size to approximately 1 MB

Checkout the two below blogs also for more info and other flags.

-> https://www.baeldung.com/jvm-configure-stack-sizes

-> https://docs.gigaspaces.com/latest/production/production-jvm-tuning.html

Increase heap size in Java

You can increase to 2GB on a 32 bit system. If you're on a 64 bit system you can go higher. No need to worry if you've chosen incorrectly, if you ask for 5g on a 32 bit system java will complain about an invalid value and quit.

As others have posted, use the cmd-line flags - e.g.

java -Xmx6g myprogram

You can get a full list (or a nearly full list, anyway) by typing java -X.

Java stack overflow error - how to increase the stack size in Eclipse?

Open the Run Configuration for your application (Run/Run Configurations..., then look for the applications entry in 'Java application').

The arguments tab has a text box Vm arguments, enter -Xss1m (or a bigger parameter for the maximum stack size). The default value is 512 kByte (SUN JDK 1.5 - don't know if it varies between vendors and versions).

Update a java thread's stack size at runtime

The stack size dynamcally updates itself as it is used so you never need to so this.

What you can set is the maximum size it can be with -Xss This is the virtual memory size used and you can make it as large as you like on 64-bit JVMs. The actual memory used is based on the amount of memory you use. ;)

EDIT: The important distinction is that the maximum size is reserved as virtual memory (so is the heap btw). i.e. the address space is reserved, which is also why it cannot be extended. In 32-bit systems you have limited address space and this can still be a problem. But in 64-bit systems, you usually have up to 256 TB of virtual memory (a processor limitation) so virtual memory is cheap. The actual memory is allocated in pages (typically 4 KB) and they are only allocated when used. This is why the memory of a Java application appears to grow over time even though the maximum heap size is allocated on startup. The same thing happens with thread stacks. Only the pages actually touched are allocated.

How to extend stack size without access to JVM settings?

To sum up the comments, you can create a new Thread and specify a stack size, though the docs say that the effects are highly platform dependent (works on my computer at least). See more here: https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/Thread.html#%3Cinit%3E(java.lang.ThreadGroup,java.lang.Runnable,java.lang.String,long)

Example:

public static void main(String[] args)
{
Thread thread1 = new Thread(null, null, "qwer", 1000000) {
public void run() {
System.out.println(countDepth());
}
};
thread1.start();
}
public static int countDepth() {
try {return 1+countDepth();}
catch(StackOverflowError err) { return 0; }
}

(change the stacksize and you will see much higher recursion depths)

JVM stack size specifications

Question, what does 1 MB stack size states in JVM as I have no idea what size a stack frame of?

A 1 MB default thread stack size means that every thread has 1MB (1048576 bytes) of stack space ... by default. The exception is if your code creates a thread using one of the Thread constructors where you can provide a stack size argument.

The size of a stack frame depends on the method being called. It needs to hold the method's parameters and local variables, so the frame size depends on their size. Each frame also needs (I think) two extra words to hold a saved frame pointer and a saved return address.

Note that in a recursive algorithm, you can have more than one stack frame for one "level of recursion". For writeObject (in Java 8), the algorithm used is recursive, and there are typically 4 frames per level of the data structure being serialized:

writeObject0 
writeOrdinaryObject
writeSerialData
defaultWriteFields
writeObject0
etcetera

The actual frame sizes will be platform dependent due to differences in compilers, and changes in the implementation of ObjectInputStream / ObjectOutputStream. You would better off trying to (roughly) measure the required stackspace rather than trying to predict frame sizes from first principles.

One more question, does every thread has 3000k stack size if I put a JVM option of -Xss3000k ?

Yes ... with the exception that I have described above.

One possible solution to your dilemma is create a special thread with an huge stack that you use for serialization. A similar thread with a huge stack will be required for deserialization. For the rest of the threads, the default stack size should be fine.

Other possible solutions:

  • Implement writeReplace and readResolve methods to flatten the parent structure of your epc objects into an array so that you don't get deep recursion. (Obviously, the flattening / unflattening needs to be done non-recursively.)

  • Do the same flattening before you call writeObject, etcetera.

  • Use a different serialization mechanism, or possible a custom one.



Related Topics



Leave a reply



Submit