5

Does anyone know if there is a way to dynamically (runtime) increase the stack size of the main Thread? Also, and I believe it is the same question, is it possible to increase / update the stack size of a Thread after its instantiation?

Thread’s CTOR allows the definition of its stack size but I can’t find any way to update it. Actually, I didn’t find any management of the stack size in the JDK (which tends to indicate that it’s not possible), everything is done in the VM.

According to the java language specification it is possible to set the stack size ‘when stack is created’ but there is a note:

A Java virtual machine implementation may provide the programmer or the user control over the initial size of Java virtual machine stacks, as well as, in the case of dynamically expanding or contracting Java virtual machine stacks, control over the maximum and minimum sizes.

IMO that’s not very clear, does that mean that some VM handle Threads with max (edit) stack sizes evolving within a given range? Can we do that with Hostpot (I didn't find any stack size related options beside Xss) ?

Thanks !

Community
  • 1
  • 1
Jerome
  • 4,472
  • 4
  • 18
  • 18
  • http://stackoverflow.com/questions/3700459/how-to-increase-to-java-stack-size have you checked this question ? theres no direct answer but good discussion on stack size management – kommradHomer Apr 13 '12 at 07:06
  • @kommradHomer it is interesting but it isn't exactly what I am looking for. I want to know if a stack size can be updated when the Thread is already running (in extreme cases, instead of crashing with a stackoverflow, a Thread would attempt to 'adapt' by increasing its stack size). – Jerome Apr 13 '12 at 07:40

2 Answers2

5

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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • All right, I understand what you meant. It doesn't answer my question but you pointed out that the reason why I asked it was wrong. Actually I thought that once you create a Thread, the whole stack size (the maximum) was reserved (to prevent fragmentation or whatever). That is untrue :) therefore there's no need to create Threads with low max stack sizes expecting them to consume less memory and then tweaking eventually their max stack size. – Jerome Apr 13 '12 at 09:16
  • care to explain a bit Peter ? Does this mean that I can -Xss104K (minimmum) and not have to worry about StackOverflow exceptions because JVM automagically ups each threads' staack size as it gets close to 104k ? Or ? – kellogs Dec 09 '13 at 13:04
  • @kellogs The operating system allocates pages to a process as it uses them. If you set the maximum to 1 MB but never use more than 100KB, then the OS only allocates 100KB of pages to that process for that thread. This works well because different threads have the same maximum but different usage of the stack. – Peter Lawrey Dec 09 '13 at 13:27
  • 1
    If this is the case, then something must be escaping me. You see, with no -Xss I was able to handle in my program some 11k threads. With -Xss104K it went up to 30k. Just by that flag alone. – kellogs Dec 09 '13 at 13:45
  • 1
    @kellogs In that case, I guess you are using a 32-bit JVM which has limited virtual memory. If you use a 64-bit JVM virtual memory is cheap and only real memory matters most of the time. – Peter Lawrey Dec 09 '13 at 14:41
  • @PeterLawrey nope, 64 bit VM. OpenJDK Runtime Environment (IcedTea6 1.12.3) (6b27-1.12.3-0ubuntu1~11.10.1) OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode) – kellogs Dec 09 '13 at 14:44
3

There's not a way to do this in the standard JDK, and even the stackSize argument isn't set in stone:

The effect of the stackSize parameter, if any, is highly platform dependent. ... On some platforms, the value of the stackSize parameter may have no effect whatsoever. ... The virtual machine is free to treat the stackSize parameter as a suggestion.

(Emphasis in original.)

yshavit
  • 42,327
  • 7
  • 87
  • 124
  • By 'set in stone' you mean final ? Yes, why didn't they set stackSize as a final variable if updating it is impossible -_- I checked if the stackSize variable of a Thread is updated once you start its execution, it's never updated (done with values such as -1, 0, 13). I don't feel like checking in openJDK for hours :s – Jerome Apr 13 '12 at 09:25
  • No, I meant that even if you pass `stackSize` to the `Thread's` constructor, there's absolutely no guarantee that the JVM will care. The docs explicitly say that the JVM is free to treat your argument as just a suggestion, or to ignore it altogether. – yshavit Apr 13 '12 at 16:25