【问题标题】:Delphi XE4 64 bit out of memoryDelphi XE4 64位内存不足
【发布时间】:2013-12-26 05:20:08
【问题描述】:

我们有一个多线程的客户端 - 服务器项目,我们最近在 64 位架构上升级了服务器端应用程序。解决了很多问题,我们的应用程序现在可以在高负载下稳定运行一周。但在此期间之后,服务器上的应用程序因“内存不足”错误而崩溃。这时候空闲内存大量可用,看来是内存碎片的问题。有没有可能对内存进行碎片整理,一些工具?或者在类似情况下可能是其他一些原因“内存不足”?

内存分配:

  1. 内存总量:96Gb
  2. 物理:48Gb
  3. 虚拟:48Gb
  4. 崩溃时的可用物理内存量:3GB
  5. 崩溃时的可用虚拟内存量:45Gb
  6. 每个线程分配的最大内存大小:1GB

【问题讨论】:

  • 也许您可以找到或设计一个内存管理器,在您的特定场景中不易受到碎片的影响。例如,如果每个线程都有自己的堆池,那么当线程终止时它会全部释放呢?

标签: delphi memory-management out-of-memory delphi-xe4


【解决方案1】:

正如您所推测的,您的问题是碎片化。您无法对内存进行碎片整理——任何尝试这样做的工具都必须拥有程序中每个指针的完整映射。请注意,即使 .NET 的垃圾收集器也无法使用大型对象堆来完成此任务,我已经崩溃了一个 32 位网络应用程序,实际使用了 100mb。

相反,您需要做的是首先避免碎片化。通常这意味着对象池,保存旧对象以供重用,而不是释放它们然后重新分配它们。

【讨论】:

  • 谢谢。 Сan您提供指向对象池实现示例的链接吗?
  • 忘了说,我们使用了 COM - 对象,它们也是如此吗?
  • 这些 COM 对象是用什么语言/RTL 编写的?
  • 大约 90% 的 COM 对象是用 Delphi 编写的,其他 COM 对象是用 C++ 编写的。是否可以为 COM 对象实现堆池?
【解决方案2】:

另一种选择(如果服务对时间要求不严格并且需要每秒 100% 在线)是每 24 小时左右重新启动一次服务(通过任务调度程序或从您自己的程序中)。

如果在您自己的程序中,您可以通过以下两种方式之一执行此操作,具体取决于您拥有的服务类型(如果您的服务可以同时存在两个实例 - 短暂 - 时间):

1) Execute a second instance of your service from within your currently running service and then terminate
2) Execute a tiny helper program that waits f.ex. 5 seconds and then (re)starts your service, then terminate your currently running service

但正如 Loren Pechtel 所写,最好的方法是首先避免碎片化。

【讨论】:

  • 谢谢,我们现在使用它:)
猜你喜欢
  • 2013-07-22
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
  • 2013-05-09
  • 2012-07-15
  • 1970-01-01
相关资源
最近更新 更多