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