Windows 7 下打开-保存对话框的问题
我使用的是德尔福2010。 我必须将 UseLatestCommonDialogs
设置为 False 并另外将“打开”和“保存”对话框的 ofOldStyleDialog
属性设置为 true 如果我希望“打开”和“保存”对话框在 Windows 7 中运行 (否则它们根本不会打开)。 我确实为堆栈保留了相当多的空间:
{$M 16384, 60048576}
因为我在大型数据集上使用递归算法。 现在我想知道问题是什么:
新对话框有时看起来非常消耗空间 它们在开始时以及在一组打开和保存之后工作 对话框执行它不再打开对话框 (也许对话框在执行后也不会释放内存?)
Windows 7 中是否有错误?
还有其他人遇到过类似的问题吗?
在带有古老对话框的 Windows 7 上工作看起来有点奇怪 (它们比 XP 风格更古老,我认为它们看起来像 Windows NT)。
任何建议将不胜感激。
提前致谢。
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:
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?)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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
$M
指定的默认堆栈空间分配对于进程中未指定其自身特定要求的所有线程来说是全局的。 60M 对于这个来说已经很大了,远远超过几乎任何堆栈所能增长到的大小。文件对话框本质上是 Windows 资源管理器的托管版本。它们将 shell 扩展加载到您的进程中,例如缩略图、列处理程序、上下文菜单等。随着 Windows 的功能越来越丰富,MS 和第三方都可以随意使用越来越多的资源(包括线程)来异步添加更多信息,而不阻塞 UI。在我的 Windows 7 64 位计算机上使用
notepad.exe
进行的简单测试显示,对话框之前有 1 个线程,但在对话框打开时有 19 个线程。在默认堆栈预留接近 60M 的 32 位进程中,需要预留超过 1G,或者默认情况下 32 位应用程序可访问的总地址空间的一半以上。如果应用程序中需要处理大量数据,则很容易发现内存碎片导致地址空间耗尽 - EXE、系统 DLL 等中的所有代码也需要安装在某个地方。 60M 的默认堆栈预留太高了,无法正常工作。您是否考虑过在您创建的线程中移动深度递归计算?不过,您需要直接使用
System
中的BeginThread()
,以便显式指定堆栈预留。或者,是否可以尝试减少算法的堆栈使用?如果要在堆栈上分配记录或数组,请考虑动态分配它们。如果您有一个经常重复出现(嵌套很深)并且有很多局部变量的函数,请考虑创建一个包含局部变量的记录并动态分配它。如果您依赖递归来排序工作(例如,树/图的深度优先遍历),请考虑使用递归来简单地排序工作(例如,将节点添加到列表中),并迭代地进行真正的处理。如果有必要,请考虑重做算法以使用显式堆栈。拥有显式堆栈的另一个优点是,您可以在需要时轻松切换到广度优先,方法是使用队列而不是堆栈,如果堆栈和队列实现使用多态接口,则可以使用单行。
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()
fromSystem
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.
谢谢你非常接近:
“如果您依赖递归来排序工作(例如,树/图的深度优先遍历),请考虑使用递归来简单地排序工作(例如,将节点添加到列表中),然后执行真正的迭代处理。”
是的,我用它来计算例如图的强连接组件。
我正在使用该算法的变体: http://en.wikipedia.org/wiki/Tarjan %27s_strongly_connected_components_algorithm
而且我不知道如何在没有递归的情况下做到这一点。
您有什么建议吗?或者指出深度的非递归算法
首先在图表上搜索?
最好的。
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.
再次感谢您提供这个非常准确的答案。
我再次测试并得到了相同的结果,正如你所写的:
其实内存问题发生时是可以预测的:
我在Delphi 2010中检查“Tread status”:
使用旧对话框时,打开/保存对话框时会出现新的步骤
打开并在关闭时从列表中删除。
当使用新对话框执行此操作时,打开/保存对话框会生成 6
执行后停止但未删除的线程,
有趣的是:在 FileName 中输入内容时
(不是通过单击鼠标从可用文件列表中选择文件)
三个新线程出现,并留在那里,所以已经有
总共 9 个“不需要”线程
然后在 Windows 任务管理器中观察,您可以看到以下情况:
“线程数” * “我的应用程序中定义的堆栈”>
“可用物理内存”+“系统缓存”
该程序将报告内存问题。
目前大约有 10 个线程打开,当然还有大堆栈
有问题。
我只在 XP 上检查过,但在 Windows 7 上,我猜,数量
生成的线程甚至更大?
有没有办法以某种方式杀死这个线程?
再次感谢,祝一切顺利。
“文件对话框本质上是 Windows 资源管理器的托管版本。它们将 shell 扩展加载到您的进程中,例如缩略图、列处理程序、上下文菜单等。随着 Windows 的功能越来越丰富,MS 和第三方都可以随意使用更多功能和更多资源 - 包括线程 - 异步添加更多信息,而不阻塞 UI 在我的 Windows 7 64 位计算机上使用 notepad.exe 进行的简单测试显示,对话框之前有 1 个线程,但对话框打开时有 19 个线程。在默认堆栈预留接近 60M 的 32 位进程中,如果正在处理大量数据,则需要预留超过 1G 或超过 32 位应用程序可访问的总地址空间的一半。根本没有申请,”
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:
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
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,"