我有一个运行/ LARGEADDRESSAWARE标志的32位Delphi应用程序。这允许在64位系统上分配高达4GB的空间。
使用线程(在池中)处理每个任务在内存中加载文件的文件。当多个线程正在运行(正在加载多个文件)时,EOutOfMemory会在某个时刻点击我。
获取可用地址空间的正确方法是什么,以便在处理下一个文件之前检查是否有足够的内存?
类似的东西:
如果TotalMemoryUsed {来自GetMemoryManagerState} + FileSize< " AvailableUpToMaxAddressSpace"然后NoOutOfMemory
我尝试过使用
AvailableUpToMaxAddressSpace的TMemoryStatusEx.ullAvailVirtual
但结果不正确(有时为0,有时>比我实际有的)。
答案 0 :(得分:1)
由于目标系统上有更多进程在运行,即使必要的基础设施可用,如果没有用。
没有保证其他进程在 之后 >你实际分配它。正确的做法是编写优雅失败的代码,并在出现时捕获EOutOfMemory
异常。使用它作为标志来停止创建更多线程,直到其中一些线程已经终止。
答案 1 :(得分:1)
我认为您不能合理且有力地期望能够提前预测内存分配是否会失败。至少,您可能需要编写专用于为应用程序提供服务的内存分配器,并且非常了解流程的堆分配要求。
实际上,您可以轻松应对的方法是摆脱32位地址空间的束缚。这是你的根本问题。从32位地址空间中逃脱的方法是编译为64位。这需要XE2或更高版本。
您可能需要继续支持32位版本的应用程序,因为您的用户仍在32位系统上。现代版本的Delphi有32位和64位编译器,编写在两种情况下都能正确编译和运行的代码非常简单。
对于32位版本,无论如何都不太可能遇到内存问题,因为32位系统往往在较旧的硬件上运行,处理器较少。反过来,这意味着对内存空间的需求减少,因为您的线程池往往更小。
如果遇到处理器数量足够大的计算机导致内存不足问题,那么一种非常简单实用的方法是为用户提供一种机制来限制应用程序线程池使用的线程数。
答案 2 :(得分:0)
Delphi是32位,因此您无法分配大于此值的内存地址。
看看这个: What is a safe Maximum Stack Size or How to measure use of stack?