views:

274

answers:

3

Hello!

I am using Delphi 2010. I have to set UseLatestCommonDialogs to False and additionally set ofOldStyleDialog property of Open and Save dialogs to true if I want that Open and Save Dialogs works in Windows 7 (otherwise they do not open at all). It is also true that I reserve quite a lot of space for a stack:

{$M 16384, 60048576}

since I use recursive algorithms on large datasets. Now I wonder what is the problem:

  1. New dialogs seem very space consuming, sometimes they work at the beginning and after a set of open and save dialogs executions it does not open dialogs any more (maybe also dialogs do not free memory after they are executed?)

  2. Is there a bug in Windows 7?

Anybody else experienced a similar problem?

It looks a little strange to work on Windows 7 with ancient dialogs (they are even older that XP style, I think they look like in Windows NT).

Any suggestion will be very appreciated.

Thanks in advance.

+12  A: 

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.

Barry Kelly
A: 

Hello!

Thanks you come very close:

"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."

Yes, I use it for computing for example strongly connected components of graphs. I am using a variant of the algorithm: http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm

And I do not see how to do it without recursion. Do you have any suggestion - or point to a non recursice algorithm for depth first search on graphs?

Best.

Petra
This is not an *answer* to the question, but a *comment* to Kelly's answer.
Andreas Rejbrand
I'd advise you to ask a separate question on that specific topic. Also, I'd delete this answer.
Barry Kelly
Actually, @Barry, they *can* comment on their own questions and answers and on others' answers to their questions.
Rob Kennedy
After some time, I must thank Barry again, that was one
Petra
of the most inportant information I got in last 10 years. I was searching for an answer for that question for more than a half year. But on the other hand such behavior of Windows 7 is very nonefficient according to RAM use and several other programs will have problems, especially the ones that use a lot of stack. The receipt is simple: "for programs under Windows 7 do not use stack".
Petra
A: 

Thanks again for this very precise answer.

I tested again and got the same result, as you wrote: Actually it can be predicted when the memory problems occur:

  1. I was checking "Tread status" in Delphi 2010: when using old dialog boxes a new tread appears when open/save dialogs opens and is removed from the list when it is closed. When doing this with new dialog boxes, open/save dialog produce 6 threads that are stoped but not removed after execution, and what is interesting: when typing something to FileName (not selecting file from the list of available files with a mouse click) three new threads appear, and stay there, so there are already altogether 9 'not needed' threads

  2. And then watching at Windows Task manager you can see that when: "number of threads" * "Stack defined in my application" > "Available Phyisical Memory" + "System Cache" The program will report memory problems.

So with about 10 threads open at the moment, and large stack of course there are problems. I was checking that only on XP, but on Windows 7, I guess, the number of threads that are generated is even larger?

And there is no way to somehow kill this threads?

Thanks again and all the best.

"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,"

Petra