我的多线程托管程序存在堆破坏问题。做了一些测试后,我发现只有在程序中的后台线程活动时(它们可以切换),才会发生破坏。这些线程使用了一些第三方组件。
通过使用.NET反编译器检查线程和第三方组件的代码,我发现它们都是托管的,即没有“unsafe”、“DllImportAttribute”或“P/Invoke”。似乎纯托管代码会导致堆破坏,这是可能的吗?
更新
除了使用Marshal类外,线程未正确同步是否可能导致堆破坏?如果有示例将会很受欢迎。
我的多线程托管程序存在堆破坏问题。做了一些测试后,我发现只有在程序中的后台线程活动时(它们可以切换),才会发生破坏。这些线程使用了一些第三方组件。
通过使用.NET反编译器检查线程和第三方组件的代码,我发现它们都是托管的,即没有“unsafe”、“DllImportAttribute”或“P/Invoke”。似乎纯托管代码会导致堆破坏,这是可能的吗?
更新
除了使用Marshal类外,线程未正确同步是否可能导致堆破坏?如果有示例将会很受欢迎。
使用不安全的代码确实可以破坏堆,但是即使不使用不安全的代码也可能破坏堆。在这种情况下,Marshal
类有时会成为你的朋友或敌人。
IntPtr ptr = new IntPtr(50000); // Random memory
byte[] b = new byte[100];
Marshalp.Copy(b, 0, ptr, 100);
这将在地址50000处的堆中有效地复制100个连续的0。
另一种方法是使用显式结构布局。
[StructLayout(LayoutKind.Explicit)]
struct S1
{
[FieldOffset(0)]
internal string str;
[FieldOffset(0)]
internal object obj;
}
S1 s = new S1();
s.obj = new Program();
s.str.Trim(); // Hope that works ... :)
LayoutKind.Explicit
才能让这个技巧起作用 / 崩溃 :) - JaredPar