2010-01-15 71 views
2

我有一個類「skImage」。這個類有一個私有變量(與公開它的公共屬性)c#如何處理內存

private Image _capturedImage; 

這個類的構造函數的樣子:

public skImage(Image captured) { 

      _capturedImage = captured; 

     } 

它還具有以下方法:

public bool Invert() { 

     Bitmap b = new Bitmap(_capturedImage); 

     unsafe { 
     //random code not relevant. 
     } 

     _capturedImage = b; 
     b.Dispose(); 
     return true; 
    } 

然後它有一個save()方法,它只是調用:

_capturedImage.Save(_saveFullLocation); 

現在,如果我運行翻轉方法,然後嘗試調用保存它會引發異常(參數無效)。谷歌搜索這個例外後,似乎我正在處理圖像。我可以看到,我在倒置方法之後部署了「b」。

我的問題是,當我做_capturedImage = b這是否意味着這兩個變量現在持有一個對象的引用?我不想那樣。我希望b被銷燬以減輕記憶,因此GC可以收集它。我如何將b傳遞給_capturedImage並銷燬b。

感謝

回答

3

這是否意味着這兩個變量現在持有一個對象的引用?

是的。然而,參考只是一個參考 - 它不會花費太多的內存。

我希望B被摧毀

你不能摧毀一個參考 - 你只能處理對象本身。

相反處置B您應該寫的:

_capturedImage.Dispose(); 
_capturedImage = b; 
+0

將意味着當b超出範圍(即方法已完成)GC將收集b並釋放與其關聯的所有內存? – masfenix 2010-01-15 19:09:22

+0

@masfenix - 引用b在Invert方法的堆棧框架上創建 - 當該方法返回時,b將不再存在。但是,b引用的對象(位圖)仍將存在於堆上(直到它被垃圾收集爲止)。 – mbeckish 2010-01-15 19:13:20

+0

要添加到mbeckish的評論中,該對象將不會被垃圾收集(嗯,現在不是),因爲位圖仍然由_capturedImage指向。 – Brian 2010-01-15 19:17:23

-2

image.Clone()

你必須把結果給您的數據再次輸入,雖然因爲clone()返回一個System.Object。

編輯:我一定誤解了這個問題。我以爲你想要一個無法在其他地方被代碼處置的圖像。只要您在內存中共享對同一圖像的引用,其他所有意識到該圖像的人都可以處理該圖像,從而有效地將您搞砸。通過克隆映像,確保沒有其他人(或您編寫的其他代碼)可以處理它。

+0

我該怎麼克隆?而不是_capturedImage = b,我應該做_capturedImage = b.clone(); ?? – masfenix 2010-01-15 19:05:29

+0

爲什麼克隆圖像? – Matthias 2010-01-15 19:05:48

+1

-1:克隆一個物體並處理原物幾乎肯定是一種愚蠢的行爲。 – Brian 2010-01-15 19:07:35

2

_capturedImage和b是相同的基礎對象引用。調用b.Dispose();也會處理_capturedImage,因爲它們都是指向相同數據塊的引用。一旦b超出範圍(即Invert返回),b將停止存在,但GC將不會收集數據,因爲_capturedImage仍指向它。

0

正如其他人所提到的,您正在將b和_capturedImage指向同一個對象,因此當您處理b時,_capturedImage也會顯示出來。

我沒有看到任何需要在這裏調用Dipose()。該變量在函數的範圍內聲明,所以它將沒有引用,GC將自動清除它。

事實上,我甚至不看爲「B」變量的需要。你爲什麼不在整個函數中使用'_capturedImage'並且保持簡單?

1

當你必須創建一個新的位圖來替換另一個位圖時,一般的經驗法則是保存對舊位圖的引用,將新引用保存到用於存儲它的變量中,然後丟棄舊位圖。

這樣,你應該有相關的存儲變量修改任何行爲,避免「閃爍」。這通常用於雙緩衝;

public bool Invert() 
{ 
    //this will create a clone of _captureImage, so you effectivly have 2 Bitmaps at that point 
    Bitmap b = new Bitmap(_capturedImage); 

    unsafe 
    { 
    //random code not relevant. 
    } 

    var old = _capturedImage; //store old reference 

    //assign, any events will seemlesly transition from the old to the new Bitmap 
    _capturedImage = b; 
    old.Dispose(); //get rid of the old Bitmap 

    return true; 
}