我是一个有用的助手,可以为您翻译文本。
我正在开发一个使用Haskell DLL(GHC版本为8.0.1 x64)的C++项目。我注意到,执行程序消耗了很多内存。我对此进行了调查,以下是我的发现。让我们考虑以下最小示例。这是由三个文件组成的小项目。
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
包含至少一个foreign export
函数时才会导致内存泄漏。
hs_init
来初始化运行时系统吗? - mschmidths_init
,消耗内存的行为都是相同的。 - O.Phillips