2011-09-27 98 views
11

我的多線程託管程序中存在堆損壞。做了一些測試後,我發現只有當程序中的後臺線程處於活動狀態(它們是可切換的)時纔會發生損壞。線程使用一些第三方組件。.NET 4:託管代碼是否會導致堆損壞?

檢查線程和第三方組件的代碼(使用.NET反射)後,我發現他們都得到管理,即沒有「不安全」或「DllImportAttribute」或「P/Invoke的」。看起來純粹的託管代碼會導致堆損壞,這可能嗎?

UPDATE

除了使用Marshal類,是有可能損壞具有螺紋堆不被正確地同步?一個例子將非常感激。

+2

只是因爲他們是全部管理,並不意味着一切都是線程安全的。你是否確保代碼以線程安全的方式執行,在需要的地方使用鎖等? –

+0

也有元帥類方法可以做到這一點。 –

+2

@ChrisDunaway,你是說不正確的鎖定或以非線程安全的方式執行線程可以破壞堆,即使不使用Marshal類?我有一個答案,這是不可能的([這裏](http://stackoverflow.com/questions/7471288/what-tools-are-available-to-detect-heap-corruption-in-net-c-program/ 7471468#7471468))。 –

回答

12

絕對有可能在不使用任何不安全代碼的情況下破壞堆。 Marshal類的地址爲你的朋友/敵人在這裏

IntPtr ptr = new IntPtr(50000); // Random memory 
byte[] b = new byte[100]; 
Marshalp.Copy(b, 0, ptr, 100); 

這有效地複製100個連續的0到堆中50000

另一種方式是明確的結構佈局

[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 ... :) 
+0

Re。結構體,普通'[StructLayout(LayoutKind.Sequential)]'不會導致堆腐敗,對吧? –

+0

@net_prog不,''LayoutKind.Explicit'需要這個技巧才能工作/崩潰:) – JaredPar

+0

@net_prog in * general *託管代碼無法破壞堆。這些只是一些......可能導致它的極端情況。這是*可能*但是你碰到CLR錯誤的可能性不大。 – JaredPar