我有下面的代碼,這將產生一個OutOfMemoryException
運行時:什麼是GarbageCollector的替代方案?
public partial class MainWindow : Window
{
private DrawingVisual myVisual = new DrawingVisual();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
myVisual = GetVisual();
graphicsCanvas.AddVisual(myVisual);
}
private void Graphics_Canvas_MouseMove(object sender, MouseEventArgs e)
{
//get the data visual:
DrawingVisual tempVisual = GetVisual();
//first clear the current display data:
graphicsCanvas.RemoveVisual(myVisual);
//get the data visual:
myVisual = tempVisual;
graphicsCanvas.AddVisual(myVisual);
//GC.Collect();
}
private DrawingVisual GetVisual()
{
double width = graphicsCanvas.ActualWidth;
double height = graphicsCanvas.ActualHeight;
DrawingVisual dV = new DrawingVisual();
Rect clipRect = new Rect(0, 0, width, height);
dV.Clip = new RectangleGeometry(clipRect);
using (DrawingContext dC = dV.RenderOpen())
{
RenderTargetBitmap rTB = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
if (rTB.CanFreeze)
{
rTB.Freeze();
}
dC.DrawImage(rTB, clipRect);
}
return dV;
}
}
凡Graphics_Canvas
定義如下:
class Graphics_Canvas : Canvas
{
private List<DrawingVisual> visuals = new List<DrawingVisual>();
protected override int VisualChildrenCount
{
get { return visuals.Count; }
}
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
public void AddVisual(DrawingVisual visual)
{
visuals.Add(visual);
base.AddVisualChild(visual);
base.AddLogicalChild(visual);
}
public bool ContainsVisual(DrawingVisual visual)
{
return visuals.Contains(visual);
}
public bool HasVisuals
{
get { return visuals.Count > 0; }
}
public void RemoveAllVisuals()
{
for (int i = 0; i < visuals.Count; i++)
{
RemoveFromLogicalTree(visuals[i]);
}
visuals.Clear();
}
private void RemoveFromLogicalTree(Visual visual)
{
RemoveLogicalChild(visual);
RemoveVisualChild(visual);
}
public void RemoveLastVisual()
{
if (visuals.Count > 0)
{
int index = visuals.Count - 1;
RemoveFromLogicalTree(visuals[index]);
visuals.Remove(visuals[index]);
}
}
public void RemoveVisual(DrawingVisual visual)
{
RemoveFromLogicalTree(visual);
visuals.Remove(visual);
}
}
而XAML創建Window
是這樣的:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:csMemoryLeakTestProject" x:Class="csMemoryLeakTestProject.MainWindow"
Title="MainWindow"
Background="Gray"
Height="600" Width="800"
WindowStartupLocation="CenterScreen"
Loaded="Window_Loaded">
<Grid>
<local:Graphics_Canvas Margin="12" Background="White" x:Name="graphicsCanvas" MouseMove="Graphics_Canvas_MouseMove"/>
</Grid>
</Window>
現在,這只是一個例子來說明我的觀點,那就是我不明白wh在另一種方法是在這裏使用的垃圾收集器...
如果你運行該程序,並保持在Graphics_Canvas
移動鼠標,內存使用建立和建立,並建立,直到你得到一個OutOfMemoryException
。如果你在GC.Collect()
的地方添加了我已經評論過的內容,這種情況不會發生(儘管由於我之外的原因,內存增加了一小部分,並希望與我的問題聯繫起來),並且程序繼續運行。
那麼,爲什麼GC
不啓動並清除此內存並停止發生異常?如果我正在做一些非常根本性的錯誤,我會很高興有人向我指出這一點,以便我可以超越這一點。
我在這個網站上看過很多次,還有一些程序員的建議是「永遠不要使用垃圾收集器」。我想遵守最佳做法,但在這種情況下我沒有看到我可以做什麼。
完全誠實;我覺得奇怪,系統會在嘗試'GC.Collect()'之前拋出'OutOfMemoryException' **。只是我的兩分錢。 – Nolonar 2013-03-25 09:32:58
等待,代碼首先*刪除*一個元素,然後添加另一個元素。沒關係。 – 2013-03-25 09:34:55
「首先清除當前顯示數據」部分呢? – RichieHindle 2013-03-25 09:42:46