从 C# 中的C++ DLL 获取回调时,WinXP 中的内存限制是多少?
What's the memory limit in WinXP when getting a callback from a C++ DLL in C#?
我有一个使用非托管c++ DLL的c#应用程序。我发现当我从c++ DLL传递回来的内存太大时,只发生在WinXP(不是Win7)中崩溃。
基本流程是c#通过调用start函数在c++ DLL中启动一个操作,该函数提供了一个回调函数。然后,c++ DLL执行该操作并将日志信息转储到文本缓冲区中。当操作完成后,c++ DLL调用回调函数并将文本缓冲区作为参数传递:
c++:typedef void (CALLBACK *onfilecallbackfunc_t)(LPCWSTR);
DLL_API void NWAperture_SetOnFileCallback(onfilecallbackfunc_t p_pCallback);
l_pFileCallback(_wstringCapture.c_str());
c#: public delegate void FileCallback([MarshalAs(UnmanagedType.LPWStr)] string buffer);
public static extern void SetOnFileCallback(FileCallback fileCallback);
private void OnFile(string buffer);
这在Win7中工作得很好,但在WinXP中,如果缓冲区太大就会崩溃。我不确定导致这种情况的确切大小,但我已经设置了8MB的限制,崩溃已经消失了。
有谁知道在WinXP中可以在c++和c#之间传输的内存量的限制吗?还是我完全误解了这个问题,还有更合理的解释?
更新:我应该更具体-这发生在WinXP和Win7双启动的同一台PC上,都是32位操作系统
所以最后证明我是个白痴。为了使日志大,但加快测试速度,我点击取消按钮,它调用了c++ DLL中的一个函数,该函数停止执行,并调用了回调函数与"中止"错误和任何日志已经记录。但是当我这样做的时候,执行并没有立即停止,所以当带有日志的回调正在进行时,c++代码可能会尝试添加到日志中。这导致了我所看到的不稳定。
我通过在日志周围使用临界区来修复它。
您可以在实际耗尽RAM之前耗尽连续内存。这是使用数组缓冲区的一个很大的缺点。LinkedLists(或使用分块的数组)有助于缓解这个问题,因为你需要的空间不必是连续的。
因此,除非您的应用程序使用2+ GB的RAM,否则您的问题更可能是内存碎片。
Windows 7可能是管理内存不同于Windows XP,这可能是为什么你没有看到问题在那里。但是如果推送更多的数据,我相信你也会遇到同样的问题。
您可以设置perfmon来跟踪/记录系统的内存使用情况,设置任务管理器来跟踪应用程序。
我不知道Windows或NETFX设置了任何硬限制,但我高度怀疑从您的c++应用程序返回的数据量可能完全是任意的,这可能导致不稳定的行为。
我强烈建议考虑将日志数据写入本机组件中的文件,然后从托管代码中读取该文件。这样,无论记录了多少数据,托管代码都可以解析它,而不必担心会破坏它的堆。
- 必须为 C++20 协程帧保留多少内存?
- 在内存不足之前,我可以声明多少个 const 变量?
- 可以读入进程内存的最大块大小是多少?
- 实际上,C++11 中 std::atomic 的内存占用量是多少?
- 在 Windows 中使用 C++ 可以分配的动态内存的最大大小是多少?
- 堆栈上的参考用途有多少内存
- 每个对象内存分配有多少开销
- 指针数组中将有多少内存分配
- 一个 Excel XLL 插件可以有多少内存?
- 在C 中存储对对象的引用需要多少内存
- Linux如何知道过程使用了多少物理内存
- 对象指针如何知道要删除多少内存
- 如果我使用共享内存,可以分配多少个块
- 在类方法中使用新运算符动态分配内存的寿命和范围是多少
- 64位Windows上应用程序的最大可用内存是多少
- 使用犰狳线性代数包存储矩阵需要多少内存
- 一个程序将分配多少堆栈内存
- std::vector-他将分配多少内存(在重新分配期间)
- 一个C++指针使用多少内存
- x64 进程可以在 4GB RAM 上占用多少内存