The default stack space allocation specified by $M
is global to all threads in the process that don't specify their own specific requirements. 60M is a lot for this, far more than almost any stack will ever grow to.
The File dialogs are essentially a hosted version of Windows Explorer. They load up shell extensions into your process for things like thumbnails, column handlers, context menus, etc. As Windows grows more featured, both MS and third parties feel free to use more and more resources - including threads - to add more info asynchronously, without blocking the UI. A simple test with notepad.exe
on my Windows 7 64-bit machine shows that it has 1 thread before the dialog, but 19 threads while the dialog is open. In a 32-bit process with a default stack reservation close to 60M, that would want to reserve over 1G, or over half the total address space accessible to 32-bit applications by default. If there's much data being worked with in the application at all, it's very easy to see one running out of address space through memory fragmentation - all the code from the EXE, system DLLs, etc. needs to fit in there somewhere too. 60M is simply too high a default stack reservation to expect to work without problems.
Have you considered moving your deeply recursive computations in a thread you create? You'd need to use BeginThread()
from System
directly though, in order to explicitly specify the stack reservation.
Alternatively, is it possible to try reducing the stack usage of your algorithms? If you're allocating records or arrays on the stack, consider allocating them dynamically. If you have a function which recurs a lot (nested deeply) and has a lot of local variables, consider creating a record containing the locals and allocating it dynamically. If you're depending on the recursion to sequence work (e.g. depth-first traversals of trees / graphs), consider using the recursion simply to sequence work (e.g. add nodes to a list), and do the real processing iteratively. And if necessary, look at redoing the algorithm to work with an explicit stack. Another advantage of having an explicit stack is that you can trivially switch to breadth-first when desired, by using a queue instead of a stack, a one-liner if the stack and queue implementations use a polymorphic interface.