【问题标题】:Hoard Memory Manager囤积内存管理器
【发布时间】:2014-07-25 12:01:00
【问题描述】:

如何在 Delphi 中使用Hoard Memory Manager?我正在寻找FastMM 的替代品,这对于严肃的多线程服务器应用程序来说是没有希望的。我查看了ScaleMM2,但它在 64 位中不稳定。

如何静态链接Hoard Memory Manager。因为它带有一个OBJ 文件。

【问题讨论】:

    标签: delphi delphi-xe6


    【解决方案1】:

    正如大卫所说,您需要一个 .dll 版本。如果您不能自己构建它,您可以找到预构建的版本。仅快速搜索turned up an older version, though

    André Mussche modified the FastCode MM Challenge 将在 2011 年添加 Hoard。如果您 browse the source code,您将看到如何使用它的示例,包括 winhoard.dll 的另一个预编译副本。但是,performancememory usage 在这些测试中表现不佳。

    【讨论】:

    • 与此相反,在我的应用程序中,当我测试 Hoard 时,FastMM 有了明显的改进。所以在我看来,不同的应用程序可能更适合或更差地适合特定的内存管理器。事实上,这是非常值得期待的。对于非常高性能的代码,设计为它们所服务的特定环境设计的定制分配器并非不值得。
    • FWIW,你链接到的源代码有这个单元:http://scalemm.googlecode.com/svn/trunk/Challenge/HoardMM.pas,它有这个声明msvcrtDLL = 'libhoard.dll',这让我发笑。事实上,这段代码和这段代码 (scalemm.googlecode.com/svn/trunk/Challenge/msvcrtMM.pas) 似乎是由我编写的!
    • 是的,没关系。无论如何,写它并不难。我希望我将它发布在 Stack 或某人的博客上。 更新:这里是:stackoverflow.com/questions/6072269/…
    • 我不会声称所有的 FastCode 测试都代表了真实世界的场景。如果存在更好的通用基准,它可能更具代表性。
    • 我怀疑这很难实现。因为不同的应用程序可能有非常不同的内存使用模式,我相信不可能针对所有合理的使用模式进行优化。我认为任何希望提高应用程序性能的人都可以通过尝试应用程序设置中的可用选项来获得最佳服务。真实世界的基准。顺便说一句 +1。
    【解决方案2】:

    您不能真正希望静态链接 Hoard,因为它是用 C++ 实现的,因此需要 C++ 运行时。您不能期望在您的 Delphi 程序中放置 C++ 运行时。

    因此,您需要在 DLL 中构建 Hoard 内存管理器,例如使用 Visual Studio。该 DLL 必须导出 mallocfreerealloc。使用 .def 文件执行此操作。然后创建一个简单的 Delphi 单元,它链接到 DLL 并安装基于这些导入函数的内存管理器。使用我对other question 的回答来指导您。与往常一样,使内存管理器单元成为 .dpr 文件使用列表中的第一个单元。

    请确保您遵守许可。如果我没记错的话,你需要支付商业许可证,或者根据 GPL 许可你的软件。

    FWIW,我在msvcrt.dll 中使用来自系统 C 运行时的malloc,它的扩展性比 FastMM 好。

    【讨论】:

    • 很大程度上取决于应用程序。 IIRC,对于我的应用程序,hoard 比 msvcrt 和 FastMM 好一点(略微),但明显更差。但是现代 msvcrt (Vista+) 比旧版本 (XP) IIRC 更好。但其他基准得出不同的结论。就我而言,我做过的最好的改变是尽可能停止使用堆。
    • 也许可以。这可能需要一点努力。很可能有一些初始化步骤需要特殊处理。就性能而言,Borland 编译器可能比 MS 或 Intel 编译器差。所以静态链接可能有点棘手。还有 GPL 问题。
    • 好吧,Hoard 是用 C 语言编写的,所以 C++ 并不适用。是的,您可以尝试链接 MSVC 生成的 .obj 文件。这不是世界上最简单的任务。特别是对于一段复杂的代码。可能需要忍者技能。
    • 其实我错了。 Hoard 是用 C++ 实现的。所以你需要坚持使用 DLL。
    • 我们一直使用 C 代码中的 C++ 代码。这很简单。所需要的只是一个与 C 兼容的接口。其中一部分意味着使函数具有 C 链接,您可以使用 extern "C" 来实现。这具有不使用 C++ 名称修饰的副作用。例如,查看libhoard.cpp 的结尾。将它与 Delphi 链接并不一定那么容易,因为您还必须提供指向 C 和 C++ 标准库的链接。 C 和 C++ 编译器会自动执行此操作,但 Delphi 不会。
    【解决方案3】:

    由于大家FAILED提供了详细的解决方案。这是一个实际可行的解决方案。

    1:打开libhoard.cpp 2:在代码中添加以下几行。

    extern "C"{
    
    __declspec(dllexport) void* scalable_malloc (size_t size)
    {
        return malloc(size);
    }
    
    __declspec(dllexport) void* scalable_realloc (void* ptr, size_t size)
    {
        return realloc(ptr, size);
    }
    
    __declspec(dllexport) void scalable_free (void* ptr)
    {
        free(ptr);
    }
    
    }
    

    3:使用nmake windows编译

    4:使用它

    unit hoard_mm;
    
    interface
    
    implementation
    
    type
      size_t = Cardinal;
    
    const
      hoardDLL = 'libhoard.dll';
    
    function scalable_malloc(Size: size_t): Pointer; cdecl; external hoardDLL;
    function scalable_realloc(P: Pointer; Size: size_t): Pointer; cdecl; external hoardDLL;
    procedure scalable_free(P: Pointer); cdecl; external hoardDLL;
    
    function GetMem(Size: NativeInt): Pointer; inline;
    begin
      Result := scalable_malloc(size);
    end;
    
    function FreeMem(P: Pointer): Integer; inline;
    begin
      scalable_free(P);
      Result := 0;
    end;
    
    function ReallocMem(P: Pointer; Size: NativeInt): Pointer; inline;
    begin
      Result := scalable_realloc(P, Size);
    end;
    
    function AllocMem(Size: NativeInt): Pointer; inline;
    begin
      Result := GetMem(Size);
      if Assigned(Result) then
      FillChar(Result^, Size, 0);
    end;
    
    function RegisterUnregisterExpectedMemoryLeak(P: Pointer): Boolean; inline;
    begin
      Result := False;
    end;
    
    const
      MemoryManager: TMemoryManagerEx = (
        GetMem: GetMem;
        FreeMem: FreeMem;
        ReallocMem: ReallocMem;
        AllocMem: AllocMem;
        RegisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak;
        UnregisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak
      );
    
    initialization
      SetMemoryManager(MemoryManager);
    
    end.
    

    【讨论】:

    • 你太卑鄙了。这正是我们一遍又一遍地告诉你要做的事情。它甚至是我的代码!而且您导出的功能很糟糕。使用 .def 文件执行此操作。而且你没有回答所有问题。答案旨在解决所提出的问题。而且您没有正确格式化代码。你真的很了不起。
    • 阅读问题。你在哪里要求详细的解决方案?你的回答和我的有什么不同?我假设您能够构建 DLL 和导出函数。我没有意识到你需要告诉如何做到这一点。有据可查的东西。而你做得很糟糕。使用 .def 文件执行此操作,以便直接导出函数。你没有回答所有问题。您没有格式化代码。这是我写的代码!
    • @DavidHeffernan 对。
    • 我们试图提供帮助没有多大意义。你似乎不想听我们的。为什么不直接导出 malloc、realloc 和 free 呢?如果您要发布其他人的代码,请将其归功于他们,否则看起来您是在声称它是您自己的。
    猜你喜欢
    • 2012-03-01
    • 1970-01-01
    • 2011-07-07
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    相关资源
    最近更新 更多