加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Haskell DLL导致内存泄漏

发布时间:2020-12-14 05:34:37 所属栏目:Windows 来源:网络整理
导读:我正在使用一个使用 Haskell DLL的C项目(GHC版本是8.0.1 x64).我注意到,执行程序消耗了大量内存.我调查了这件事,这就是我发现的.让我们考虑以下最小的例子.这是一个由三个文件组成的小项目. HaskellExports.hs {-# LANGUAGE ForeignFunctionInterface #-}mod
我正在使用一个使用 Haskell DLL的C项目(GHC版本是8.0.1 x64).我注意到,执行程序消耗了大量内存.我调查了这件事,这就是我发现的.让我们考虑以下最小的例子.这是一个由三个文件组成的小项目.

HaskellExports.hs

{-# LANGUAGE ForeignFunctionInterface #-}
module HaskellExports where

import Foreign.C.Types
import Foreign.StablePtr

foreign export ccall foo :: CInt -> IO (StablePtr Int)

foo :: CInt -> IO (StablePtr Int)
foo (CInt n) = newStablePtr (fromIntegral n)

包含一个应该从C/C++代码调用的函数.

CWrapper.cpp

#define DLLExport extern "C" __declspec(dllexport) 

DLLExport void* c_smth (const int num)
{
    return 0;
}

我故意没有包含Haskell函数的实际导出,因为它们对这个例子没有任何影响.

main.cpp中

#include <Windows.h>

int main()
{
    for (;;)
    {
        HINSTANCE module = ::LoadLibrary(L"HaskellExports.dll");
        ::FreeLibrary(module);
    }
    return 0;
}

在这里,在无限循环中,我加载库并立即释放它.让我们尝试以两种不同的方式构建DLL.首先,我们不要包含Haskell对象文件:

ghc -c HaskellExports.hs
ghc -c CWrapper.cpp 
ghc -shared -no-hs-main -o HaskellExports.dll CWrapper.o

我运行该程序并注意到(在Windows进程监视器的帮助下),内存资源被正确捕获和释放.

现在让我们添加Haskell对象文件:

ghc -c HaskellExports.hs
ghc -c CWrapper.cpp 
ghc -shared -no-hs-main -o HaskellExports.dll CWrapper.o HaskellExports.o

我再次运行该程序并注意到,它在很长一段时间内消耗了越来越多的内存而无意释放它.这种情况导致崩溃.

我究竟做错了什么?

附:进一步的调查表明,只有当HaskellExport.hs包含至少一个外部导出函数时才会导致内存泄漏.

解决方法

我决定发电子邮件到ghc-devs邮件列表. (要阅读所有通信,请参阅 the question和更多消息,答案可以在 here找到).

简要说明.内存泄漏是由于以下原因引起的:对于每个外部导出,RTS创建一个静态C包装器,它在DLL_PROCESS_ATTACH上初始化,但在DLL_PROCESS_DETACH期间没有终结器/析构函数.所以它会一直存在,直到程序终止.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读