- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
注意:32 位应用程序,不计划迁移到 64 位。
我正在使用一个非常消耗内存的应用程序,并且已经优化了与内存分配/取消分配相关的所有相关路径。 (应用程序本身没有内存泄漏,没有句柄泄漏,没有任何其他类型的泄漏,据我所知并经过测试。我无法触及的第 3 方库当然是候选库,但在我的场景中不太可能)
应用程序将经常分配大型单维和二维动态数组,其中包含最多 4 个单条记录和打包记录。总的来说,我的意思是 5000x5000 的记录(单个、单个、单个、单个)是正常的。在给定时间甚至有 6 或 7 个这样的阵列在工作。这是必需的,因为在这些阵列上进行了大量交叉计算,并且从磁盘读取它们将是真正的性能 killer 。
澄清这一点后,我经常遇到内存不足错误,因为这些大型动态数组在释放它们后不会消失,无论我将它们设置为 0 还是最终确定它们。这当然是FastMM为了快而做的事情,我就知道这么多。
我使用以下方法跟踪 FastMM 分配的 block 和进程消耗的内存 (RAM + PF):
function CurrentProcessMemory(AWaitForConsistentRead:boolean): Cardinal;
var
MemCounters: TProcessMemoryCounters;
LastRead:Cardinal;
maxCnt:integer;
begin
result := 0;// stupid D2010 compiler warning
maxCnt := 0;
repeat
Inc(maxCnt);
// this is a stabilization loop;
// in tight loops, the system doesn't get
// much chance to release allocated resources, which in turn will get falsely
// reported by this function as still being used, resulting in a false-positive
// memory leak report in the application.
// so we do a tight loop here, waiting, until the application reported memory
// gets stable.
LastRead := result;
MemCounters.cb := SizeOf(MemCounters);
if GetProcessMemoryInfo(GetCurrentProcess,
@MemCounters,
SizeOf(MemCounters)) then
Result := MemCounters.WorkingSetSize + MemCounters.PagefileUsage
else
RaiseLastOSError;
if AWaitForConsistentRead and (LastRead <> 0) and (abs(LastRead - result)>1024) then
begin
sleep(60);
application.processmessages;
end;
until (not AWaitForConsistentRead) or (abs(LastRead - result)<1024) or (maxCnt>1000);
// 60 seconds wait is a bit too much
// so if the system is that "unstable", let's just forget it.
end;
function CurrentFastMMMemory:Cardinal;
var mem:TMemoryManagerUsageSummary;
begin
GetMemoryManagerUsageSummary(mem);
result := mem.AllocatedBytes + mem.OverheadBytes;
end;
我在 64 位计算机上运行代码,崩溃前的最大内存消耗约为 3.3 - 3.4 GB。之后,我在应用程序的任何地方都会遇到与内存/资源相关的崩溃。我花了一些时间来确定埋藏在某些第三方库中的大型动态数组的使用情况。
我克服这个问题的方法是,通过重新启动应用程序并使用某些参数关闭,使应用程序从中断处自行恢复。如果内存消耗合理并且当前操作完成,这一切都很好。
当当前内存使用量为 1GB,而下一个要处理的操作需要 2.5 GB 内存或更多内存时,就会出现大问题。我当前的代码在恢复之前将其自身限制为 1.5 GB 的已用内存上限,但在这种情况下,我必须将限制降至 1 GB 以下,这基本上会让应用程序在每次操作后自行恢复,甚至不能保证一切都会好起来的。
如果另一个操作需要处理更大的数据集并且总共需要 4GB 或更多内存怎么办?
要注意的是,我并不是在谈论实际的 4 GB 内存,而是通过分配巨大的动态数组来消耗内存,一旦取消分配,操作系统就不会收回这些数组,因此它仍然将其视为已消耗的内存,因此它会加起来.
所以,我的下一个攻击点是强制 fastmm 释放操作系统的所有(或至少部分)内存。我在这里专门针对巨大的动态数组。同样,这些位于第三方库中,因此重新编码并不是真正的首选选项。修改 fastmm 代码并编写一个过程来释放内存会更容易、更快捷。
我无法从 FastMM 切换,因为目前整个应用程序和一些第 3 方库都围绕 PushAllocationGroup 的使用进行了大量编码,以便快速查找并查明任何内存泄漏。我知道我可以编写一个虚拟的 FastMM 单元来解决编译引用问题,但我将无法进行这种快速且确定的泄漏检测。
总结:有什么方法可以强制 FastMM 至少将一些大块释放到操作系统吗? (嗯,当然有,实际的问题是:有人写过它吗?如果是的话,介意分享吗?)
谢谢
稍后编辑:
我很快就会想出一个小型的相关测试应用程序。模拟一个似乎并不那么容易
最佳答案
我怀疑问题实际上是由 FastMM 造成的。对于巨大的内存块,FastMM不会进行任何子分配。您的分配请求将通过直接的 VirtualAlloc
进行处理。然后释放是VirtualFree
。
假设您在一个连续的 block 中分配这些 380MB 的对象。我怀疑你实际上拥有的是不规则的二维动态数组。而且它们不是单一分配。 5000x5000 不规则的二维动态数组需要 5001 次分配来初始化。 1 个用于行指针,5000 个用于行。这些将是中等 FastMM block 。会有二次分配。
我觉得你的要求太多了。根据我的经验,只要 32 位进程需要超过 3GB 的内存,游戏就结束了。地址空间碎片会在内存耗尽之前阻止您。你不能指望这能起作用。切换到 64 位,或者使用更聪明、要求更低的分配模式。或者你真的需要密集的二维阵列吗?可以使用稀疏存储吗?
如果您无法通过这种方式缓解内存需求,您可以使用内存映射文件。这将允许您利用 64 位系统拥有的额外内存。系统的磁盘缓存可以大于 4GB,因此您的应用程序可以遍历超过 4GB 的内存,而无需实际访问磁盘。
您当然可以尝试不同的内存管理器。老实说,我不抱任何希望它会有所帮助。您可以编写一个使用 HeapAlloc
的简单替换内存管理器。并启用低碎片堆(从 Vista 开始默认启用)。但我真诚地怀疑这是否会有帮助。恐怕没有快速的办法可以解决你的问题。要解决此问题,您需要对代码进行更根本的修改。
关于delphi - 如何解决内存分段并强制FastMM释放内存给OS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20668182/
@Cacheable在同一类中方法调用无效 上述图片中,同一个类中genLiveBullets()方法调用同类中的queryLiveByRoom()方法,这样即便标识了Cacheable标签,
目录 @Transaction注解导致动态切换更改数据库失效 使用场景 遇到问题 解决 @Transaction
@RequestBody不能class类型匹配 在首次第一次尝试使用@RequestBody注解 开始加载字符串使用post提交(貌似只能post),加Json数据格式传输的时候,
目录 @Autowired注入static接口问题 @Autowired自动注入普通service很方便 但是如果注入static修饰的serv
目录 @RequestBody部分属性丢失 问题描述 JavaBean实现 Controller实现
目录 解决@PathVariable参数接收不完整的问题 今天遇到的问题是: 解决办法: @PathVariable接受的参
这几天在项目里面发现我使用@Transactional注解事务之后,抛了异常居然不回滚。后来终于找到了原因。 如果你也出现了这种情况,可以从下面开始排查。 1、特性 先来了解一下@Trans
概述: ? 1
场景: 在处理定时任务时,由于这几个方法都是静态方法,在aop的切面中使用@Around注解,进行监控方法调用是否有异常。 发现aop没有生效。 代码如下:
最近做项目的时候 用户提出要上传大图片 一张图片有可能十几兆 本来用的第三方的上传控件 有限制图片上传大小的设置 以前设置的是2M&nb
我已经实现了这个SCIM reference code在我们的应用程序中。 我实现的代码确实通过了此postman link中存在的所有用户测试集合。 。我的 SCIM Api 也被 Azure 接受
我一直对“然后”不被等待的行为感到困扰,我明白其原因。然而,我仍然需要绕过它。这是我的用例。 doWork(family) { return doWork1(family)
我正在尝试查找 channel 中的消息是否仍然存在,但是,我不确定如何解决 promise ,查看其他答案和文档,我可以看到它可能是通过函数实现的,但我是不完全确定如何去做。我希望能在这方面获得一些
我有以下情况: 同一工作区中的 2 个 Eclipse 项目:Apa 和 Bepa(为简洁起见,使用化名)。 Apa 项目引用(包括)Bepa 项目。 我在 Bepa 有一个类 X,具有公共(publ
这个问题已经有答案了: Why am I getting a NoClassDefFoundError in Java? (31 个回答) 已关闭 6 年前。 我正在努力学习 spring。所以我输入
我正在写一个小游戏,屏幕上有许多圆圈在移动。 我在两个线程中管理圈子,如下所示: public void run() { int stepCount = 0; int dx;
我在使用 Sympy 求解方程时遇到问题。当我运行代码时,例如: 打印(校正(10)) 我希望它打印一个数字 f。相反,它给我错误:执行中止。 def correction(r): from
好吧,我制作的每个页面都有这个问题。我不确定我做错了什么,但我所有的页面都不适用于所有分辨率。可能是因为我使用的是宽屏?大声笑我不确定,但在小于宽屏分辨率的情况下,它永远不会看起来正确。它的某些部分你
我正在尝试像这样进行一个非常简单的文化 srting 检查 if(culture.ToUpper() == "ES-ES" || "IT-IT") { //do something } else
Closed. This question is off-topic. It is not currently accepting answers. Learn more。 想改进这个问题吗?Upda
我是一名优秀的程序员,十分优秀!