I have a recursive function that works for input where the call stack depth is up to 1000, but fails for bigger inputs. I converted the function to be tail recursive and that allowed it to get to about 1350.
What are the limits and is there any way to increase that limit?
I am working with pure functions and would like to avoid having to use operations. I have a solution that breaks up the problem into a composition of steps, each of which has a smaller stack depth, but it is rather contrived since its only purpose is to avoid the issue and it is more complex.
This is my mistake again... the setting for the Java stack is -Xss (the -Xms setting is the starting heap size), sorry. So if you use the JVM Arguments section in the Debugger tab of the launcher, and set something like -Xss5m, you should get further.
In a simple experiment with a recursive function, the default stack allowed me a depth of 227 calls. Using -Xss5m gave me 4020 calls, and -Xss10m gave me 8050 calls. Note that these stack sizes are somewhat less that the Gb sizes you were trying - 5Mb of stack is a lot of calls!
Overture does not impose a stack limit over the underlying Java stack limit, so it will simply respect the -Xms JVM argument. I think the regular execution stack for the interpreter comes from the Overture.ini file (top level), where you see the -Xmx argument to set the maximum heap. Can you try adding (say) -Xms128m, or a size of your choice, and see whether that gets you further?
It sounds like you are asking about how to increase the Java Stack Limit in the Overture debugger and not in the Overture IDE (overture.ini).
To change pass additional arguments to the Overture debugger you need to add them to the launch configuration:
Open the launch configuration
Select the "Debugger" tab
The add your arguments to the box shown next to "Arguments:" in the top
Overture Launch configuration
I have tried with -Xms and -Xmx both set up to 2048m but without any impact. I have also tried on Overture 2.3.0 on both Mac OSX and Windows 10 with the same result.
To take my project out of the loop, I created a new project with one very simple function:
countdown(n:nat) res:nat
== if n=0 then n else countdown(n-1)
On both Windows and Mac I can call this with value 807 and be successful, while with 808 it fails with error:
internal error
Main 206: Error evaluating code
Detailed Message: internal error
Related
I have one FunSuite of unit tests testing a highly recursive (non-tail) Scala function. If I add the line below to my pom.xml Surefire <configuration> it runs twice as fast.
<argLine>-Xss1024k</argLine>
It doesn't matter what value I specify, except that if I specify a really low value like -Xss256k I get the expected StackOverflowException. Otherwise, I can set it anywhere from 512k up to 512m and the execution time is all the same. But then if I delete the line entirely from pom.xml the execution time doubles.
Why could that be?
JVM specification states,
Because the Java Virtual Machine stack is never manipulated directly
except to push and pop frames, frames may be heap allocated. The
memory for a Java Virtual Machine stack does not need to be
contiguous.
This specification permits Java Virtual Machine stacks either to be of
a fixed size or to dynamically expand and contract as required by the
computation. If the Java Virtual Machine stacks are of a fixed size,
the size of each Java Virtual Machine stack may be chosen
independently when that stack is created.
I think the jvm You are using supports dynamically expanding stacks. When chain of calls gets bigger than the default initial stack size, stack frames will be allocated from the heap. This will cause the execution to be slowed down.
And the case You specify the stack size with parameter, stack maybe work on fixed size mode. In this case all the space will be allocated before hand and no new allocations will be required. Also when You give the low stack size it does not expand and throws StackOverflow, this also shows it is working on fixed size mode.
Since You didn't mention JVM implementation You are using, this is just my assumption based on the info from the JVM specs and Your use case.
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.2
Why ILSpy is adding variables on stack instead of Instructions? I mean, when pushing or poping from/on stack it adds Ldloc and Stloc instructions. Can anyone explain why it has this behaviour? Thanks!
Because a stack slot acts like a variable: it can be used multiple times (e.g. on both branches of an if), but the effect of the instruction only happens once, when the value is pushed on the stack.
A decompiler that uses a stack of instructions would effectively cause the side effects of the instruction to instead happen at the point where the value is popped from the stack. This would be a program reordering that could subtly change program behavior -> incorrect decompilation.
In principle, using a stack of instructions would be possible within basic blocks; but when there's control flow (either outgoing or incoming) or a dup instruction, the whole stack of instructions would have to be converted to a stack of variables.
Currently the ILSpy ILReader uses a single pass (as specified in the Ecma-335 spec), so it doesn't know about incoming control flow during the ILReader run, so it has to always use a stack of variables to be safe.
It turns out that this is not how the .NET framework reads IL bytecodes, and some obfuscators are exploiting the difference. So in the future, we may rewrite the ILReader to work more like the .NET bytecode importer, at which point we might move to the mixed stack of variables+stack of instructions model. ILSpy issue #901
I am running a recursive function in MATLAB and gets this error message:
"Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N)
to change the limit. Be aware that exceeding your available stack space can
crash MATLAB and/or your computer."
I wonder, can it really happen that MATLAB and/or my computer can crash if I change the recursion limit and exceed my stack space? It seems strage to me. Why doesn't MATLAB just halt and quit automatically if the available stack space is exceeded?
And how do I know how big recursion limit I can choose without danger?
The computer isn't going to crash. Matlab might, that depends on their handling of the stack. The warning is there most likely because Matlab is multi-platform, and it can run on many different OSes and architectures, some of which might not be as safe as Windows or most POSIXes.
In practice, when working with a thread stack on a Windows machine, the "stack overflow" error is actually "access violation" - you try to access memory that doesn't belong to you not actually an access violation (instead, it's a special kind of page fault, basically), but the idea is similar - the OS notifies you first that you're reaching the ceiling of the stack, and if you exceed the last few "safety" pages, it will give you the actual stack overflow. This is very handy, since it's "free" - you don't have to check if you still have stack space every time you push, and it gives you some extra safety.
Depending on how Matlab handles that exception, it might gracefuly report an error and continue, or it might crash.
Of course, handling stack overflows can be quite tricky, but not for the OS. Windows can handle those errors just fine, it doesn't really care.
The recursion limit depends a lot on how much data Matlab actually has to store in each step of the recursion. The typical stack size of a Windows thread is about 256-1024 kiB (and it's configurable for threads you start on your own), which is actually quite a lot, unless you're passing a lot of big arguments. Consider that with a method that takes two integers and doesn't have any variables, you'd need about 20 000 call deep recursion to exceed even the 256 kiB stack space (on 32-bit).
However, stack overflows are usually a problem in code. You most often run into them by choosing the wrong recursion exit condition. That's part of the reason why the stack overflow is handled by an "exception", rather than allocating more memory for the stack - every trivial recursion error would start crashing all your applications and possibly even the OS. So, first make sure that you actually need a recursion that deep :)
Actually here is a very similar question presented by Mathworks.
Here is how they say you can produce a recursion problem, I think it had 32 bit in mind so you may need to increase the 5000:
create the following file:
function retVal = myrecursivefun(inVal, recursions)
recursions = recursions - 1;
inVal = inVal + 1;
if recursions > 0
retVal = myrecursivefun(inVal, recursions);
else
retVal = inVal;
end
Then run it as follows to crash MATLAB:
set(0,'RecursionLimit', 5000);
myrecursivefun(1, 5000);
Personal note: I think the default recursion limit of 500 makes sense. Matlab programmers won't often want to go beyond this and most of the time this limit is hit because of a mistake.
Also, I think matlab has a little more overhead for function calls than low level languages like C++, therefore you will usually want to avoid deep recursion in the first place.
I'm getting the java.lang.OutOfMemoryError exception in Eclipse. I know that Eclipse
by default uses heap size of 256M. I'm trying to increase it but nothing happens.
For example:
eclipse -vmargs -Xmx16g -XX:PermSize=2g -XX:MaxPermSize=2g
I also tried different settings, using only the -Xmx option, using different cases
of g, G, m, M, different memory sizes, but nothing helps. Tried also to specify the values in the eclipse.ini file. Does not matter which params I specify, the heap exception is thrown at the same time, so I assume there's something I'm doing wrong that Eclipse ignores the -Xmx parameter. I'm using a 32GB RAM machine and trying to execute something very simple such as:
double[][] a = new double[15000][15000];
It only works when I reduce the array size to something around 10000 on 10000.
I'm working on Linux and using the top command I can see how much memory the Java
process is consuming; it's less than 2%.
Thanks!
Okay, I found a solution after reading
Why does heap space run out only when running JUnit tests?
When I specify the -Xmx inside eclipse by going to run->configuration->vm arguments
and set the -Xmx there, everything works fine :)
I'm developing an operating system and rather than programming the kernel, I'm designing the kernel. This operating system is targeted at the x86 architecture and my target is for modern computers. The estimated number of required RAM is 256Mb or more.
What is a good size to make the stack for each thread run on the system? Should I try to design the system in such a way that the stack can be extended automatically if the maximum length is reached?
I think if I remember correctly that a page in RAM is 4k or 4096 bytes and that just doesn't seem like a lot to me. I can definitely see times, especially when using lots of recursion, that I would want to have more than 1000 integars in RAM at once. Now, the real solution would be to have the program doing this by using malloc and manage its own memory resources, but really I would like to know the user opinion on this.
Is 4k big enough for a stack with modern computer programs? Should the stack be bigger than that? Should the stack be auto-expanding to accommodate any types of sizes? I'm interested in this both from a practical developer's standpoint and a security standpoint.
Is 4k too big for a stack? Considering normal program execution, especially from the point of view of classes in C++, I notice that good source code tends to malloc/new the data it needs when classes are created, to minimize the data being thrown around in a function call.
What I haven't even gotten into is the size of the processor's cache memory. Ideally, I think the stack would reside in the cache to speed things up and I'm not sure if I need to achieve this, or if the processor can handle it for me. I was just planning on using regular boring old RAM for testing purposes. I can't decide. What are the options?
Stack size depends on what your threads are doing. My advice:
make the stack size a parameter at thread creation time (different threads will do different things, and hence will need different stack sizes)
provide a reasonable default for those who don't want to be bothered with specifying a stack size (4K appeals to the control freak in me, as it will cause the stack-profligate to, er, get the signal pretty quickly)
consider how you will detect and deal with stack overflow. Detection can be tricky. You can put guard pages--empty--at the ends of your stack, and that will generally work. But you are relying on the behavior of the Bad Thread not to leap over that moat and start polluting what lays beyond. Generally that won't happen...but then, that's what makes the really tough bugs tough. An airtight mechanism involves hacking your compiler to generate stack checking code. As for dealing with a stack overflow, you will need a dedicated stack somewhere else on which the offending thread (or its guardian angel, whoever you decide that is--you're the OS designer, after all) will run.
I would strongly recommend marking the ends of your stack with a distinctive pattern, so that when your threads run over the ends (and they always do), you can at least go in post-mortem and see that something did in fact run off its stack. A page of 0xDEADBEEF or something like that is handy.
By the way, x86 page sizes are generally 4k, but they do not have to be. You can go with a 64k size or even larger. The usual reason for larger pages is to avoid TLB misses. Again, I would make it a kernel configuration or run-time parameter.
Search for KERNEL_STACK_SIZE in linux kernel source code and you will find that it is very much architecture dependent - PAGE_SIZE, or 2*PAGE_SIZE etc (below is just some results - many intermediate output are deleted).
./arch/cris/include/asm/processor.h:
#define KERNEL_STACK_SIZE PAGE_SIZE
./arch/ia64/include/asm/ptrace.h:
# define KERNEL_STACK_SIZE_ORDER 3
# define KERNEL_STACK_SIZE_ORDER 2
# define KERNEL_STACK_SIZE_ORDER 1
# define KERNEL_STACK_SIZE_ORDER 0
#define IA64_STK_OFFSET ((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE)
#define KERNEL_STACK_SIZE IA64_STK_OFFSET
./arch/ia64/include/asm/mca.h:
u64 mca_stack[KERNEL_STACK_SIZE/8];
u64 init_stack[KERNEL_STACK_SIZE/8];
./arch/ia64/include/asm/thread_info.h:
#define THREAD_SIZE KERNEL_STACK_SIZE
./arch/ia64/include/asm/mca_asm.h:
#define MCA_PT_REGS_OFFSET ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE)
./arch/parisc/include/asm/processor.h:
#define KERNEL_STACK_SIZE (4*PAGE_SIZE)
./arch/xtensa/include/asm/ptrace.h:
#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)
./arch/microblaze/include/asm/processor.h:
# define KERNEL_STACK_SIZE 0x2000
I'll throw my two cents in to get the ball rolling:
I'm not sure what a "typical" stack size would be. I would guess maybe 8 KB per thread, and if a thread exceeds this amount, just throw an exception. However, according to this, Windows has a default reserved stack size of 1MB per thread, but it isn't committed all at once (pages are committed as they are needed). Additionally, you can request a different stack size for a given EXE at compile-time with a compiler directive. Not sure what Linux does, but I've seen references to 4 KB stacks (although I think this can be changed when you compile the kernel and I'm not sure what the default stack size is...)
This ties in with the first point. You probably want a fixed limit on how much stack each thread can get. Thus, you probably don't want to automatically allocate more stack space every time a thread exceeds its current stack space, because a buggy program that gets stuck in an infinite recursion is going to eat up all available memory.
If you are using virtual memory, you do want to make the stack growable. Forcing static allocation of stack sized, like is common in user-level threading like Qthreads and Windows Fibers is a mess. Hard to use, easy to crash. All modern OSes do grow the stack dynamically, I think usually by having a write-protected guard page or two below the current stack pointer. Writes there then tell the OS that the stack has stepped below its allocated space, and you allocate a new guard page below that and make the page that got hit writable. As long as no single function allocates more than a page of data, this works fine. Or you can use two or four guard pages to allow larger stack frames.
If you want a way to control stack size and your goal is a really controlled and efficient environment, but do not care about programming in the same style as Linux etc., go for a single-shot execution model where a task is started each time a relevant event is detected, runs to completion, and then stores any persistent data in its task data structure. In this way, all threads can share a single stack. Used in many slim real-time operating systems for automotive control and similar.
Why not make the stack size a configurable item, either stored with the program or specified when a process creates another process?
There are any number of ways you can make this configurable.
There's a guideline that states "0, 1 or n", meaning you should allow zero, one or any number (limited by other constraints such as memory) of an object - this applies to sizes of objects as well.