Windows的mallocreplace(例如,tcmalloc)和dynamic的crt链接

一个使用多个DLL和QT的C ++程序应该配备一个mallocreplace(如tcmalloc ),用于解决可由Windows malloc导致的性能问题。 有了linux,没有问题,但是使用windows,有几种方法,我觉得它们都没有吸引力:

1.将新的malloc放在lib中,并确保先链接(其他SO-问题)

这有一个缺点,例如, strdup仍然会使用旧的malloc,而且免费的可能会导致程序崩溃 。

2.使用lib.exe(Chrome)从静态libcrt库中删除malloc

这是铬/铬testing/使用(?),但有缺点,它只是与静态链接crt的作品。 静态链接有问题,如果一个系统库与msvcrtdynamic链接可能会在堆分配/取消分配不匹配 。 如果我的理解正确,tcmalloc可以被dynamic地链接起来,以便所有自编译的dll(这是很好的)有一个共同的堆。

3.补丁crt源代码(firefox)

Firefox的jemalloc显然修补了Windows CRT源代码,并构build了一个新的crt。 这又是上面的静态/dynamic链接问题。

有人可能会想到使用它来生成一个dynamic的MSVCRT,但我认为这是不可能的,因为许可证禁止提供一个打补丁MSVCRT同名。

4.在运行时dynamic修补加载的CRT

一些商业内存分配器可以做这样的魔术。 tcmalloc也可以,但是这看起来相当难看。 它有一些问题,但他们已经修复。 目前,使用tcmalloc它不能在64位窗口下工作。

有更好的方法吗? 任何意见?

问:一个C ++程序被拆分成几个dll应该:

一)取代malloc?

B)确保分配和取消分配发生在同一个dll模块中?

答:正确的答案是B.一个包含多个DLL的c ++应用程序设计应该确保一个机制的存在,以确保在一个dll堆中分配的东西,由相同的dll模块释放。


为什么你会分裂一个C ++程序到几个DLL呢? 通过c ++程序,我的意思是你正在处理的对象和类型是c + +模板,STL对象,类等。你不能通过dll边界c ++对象没有很多非常小心的设计和大量的编译器特定的魔法,或痛苦从各种dll中目标代码的大量复制,以及对版本非常敏感的应用程序。 任何对类定义的小改动都会强制重建所有的exe和dll,至少可以消除dll方法在应用程序开发中的主要优点之一。

要么坚持到应用程序和DLL之间的直接的C接口,忍受地狱,或只是编译整个C ++应用程序作为一个EXE。

这是一个大胆的说法,一个C ++程序“应该配备一个malloc替换(如tcmalloc)性能问题….”

“在8个流行的基准测试中,有6个…实际大小的应用程序取代了自定义分配器,在这个分配器中,人们投入了大量的时间和金钱…用系统提供的哑分配器[产生]更好的性能……最简单的定制分配器,针对非常特殊的情况进行调整,是唯一可以提供收益的定制分配器。 – 安德烈Alexandrescu

大多数系统分配器大致和通用分配器一样好。 只有具有非常具体的分配模式,才能做得更好。

通常情况下,这种特殊模式只适用于程序的一部分,在这种情况下,最好将自定义分配器应用于可以受益的特定部分,而不是全局替换分配器。

C ++提供了几种有选择地替换分配器的方法。 例如,你可以给STL容器提供一个分配器,或者你可以按类重写新的和删除的类。 这两种方法都可以比全局替换分配器的任何黑客更好的控制。

还要注意,替换malloc和free不一定会改变运算符new和delete使用的分配器。 虽然全局新运算符通常使用malloc来实现,但并不要求这样做。 因此,替换malloc可能甚至不会影响大部分的分配。

如果你使用C语言,你可以使用自定义的分配器来封装或者替换关键的malloc和免费的调用,而只需要在程序的其余部分使用默认的分配器。 (如果不是这样的话,你可能要考虑一些重构。)

系统分配者有数十年的发展。 他们是稳定的,经过很好的测试。 它们对于一般情况(在原始速度,线程争用和碎片方面)表现非常好。 他们有调试版本的泄漏检测和支持跟踪工具。 有些甚至通过提供针对堆缓冲区溢出漏洞的防御来提高应用程序的安全性。 很可能,您要使用的库仅在系统分配器上进行过测试。

大部分替换系统分配器的技术都丧失了这些好处。 在某些情况下,它们甚至会增加内存需求(因为它们不能与其他进程可能使用的DLL运行时共享)。 在面对编译器版本,运行时版本甚至操作系统版本的变化时,它们也往往非常脆弱。 使用经过调整的运行时版本可以防止用户从OS供应商获得运行时更新的好处。 为了保留这些好处,为了保留这些好处,可以将自定义分配器应用到可以从中受益的特殊部分。

你的前提“使用几个DLL和QT的C ++程序应该配备一个malloc替换”来自哪里?

在Windows上,如果所有的dll都使用共享的MSVCRT,则不需要替换malloc。 默认情况下,Qt建立在共享的MSVCRT DLL上。

一个人会遇到问题,如果他们:

1)混合使用静态链接与使用共享VCRT的dll

2)还有空闲的内存,它没有被分配的地方(即静态链接的DLL中的空闲内存,由共享的VCRT分配,反之亦然)。

请注意,在资源周围添加自己的ref包装可以帮助缓解与需要以特定方式释放的资源相关联的问题(即,通过回调原始dll来处理一种类型的资源的包装器,包装来源于另一个DLL的资源等)。

nedmalloc? 还要注意,smplayer使用特殊的补丁来覆盖malloc,这可能是你前进的方向。