ปัญหามีอยู่ว่า ผมโหลดภาพด้วย BitmapImage จำนวน 10 ภาพแล้วแสดงผลด้วย Image และผมต้องการที่จะลบภาพออก ปรากฏว่าเกิด Memory Leak ขึ้น โปรแกรมผมกิน Ram ไป เท่ากับตอนที่โหลดภาพ 10 ภาพ
เพื่อความสะดวกผมจะขอโหลดภาพขึ้นมาแค่ภาพเดียว เป็นไฟล์ png ขนาด 5.27MB ความละเอียด 1810x4034
public partial class MainWindow : Window { Image img; public MainWindow() { InitializeComponent(); img = new Image(); stackPanel1.Children.Add(img); } private void button1_Click(object sender, RoutedEventArgs e) { var bi = new BitmapImage(); bi.BeginInit(); bi.UriSource = new Uri(@"H:\img.png"); bi.EndInit(); if (bi.CanFreeze) bi.Freeze(); img.Width = bi.PixelWidth; img.Height = bi.PixelHeight; img.Source = bi; bi = null; img.Visibility = System.Windows.Visibility.Visible; } private void button2_Click(object sender, RoutedEventArgs e) { img.Source = null; img.Visibility = System.Windows.Visibility.Collapsed; } }
Code ข้างบนนี้เกิด Memory Leak
ผมลองเอา
img.Visibility = System.Windows.Visibility.Collapsed;
ออกปรากฏว่าปัญหา Memory Leak หายไป แต่ตัว Image ยังจองพื้นที่ใน Window อยู่จึงต้องกำหนดความกว้างกับความสูงเป็น 0 แทน
private void button2_Click(object sender, RoutedEventArgs e) { img.Source = null; img.Width = img.Height = 0.0; }
เท่านี้ก็ช่วยลด Memory ที่ใช้แล้ว ถึงจะลดได้ไม่หมด แม้ว่าจะลบ Image ออก แล้วใช้ GC.Collect() หน่วยความจำก็ไม่กลับคืนมาทั้งหมด
จะเห็นว่าตอนเปิดโปรแกรมใหม่ ๆ ใช้ Ram 14,596K
พอโหลดภาพมาแสดงใช้ Ram 72,984K
พอลบภาพออกจะใช้ Ram ลดลงเหลือ 45,032K
ตอนนี้ผมก็ยังไม่รู้จะแก้ได้ยังไง
No comments:
Post a Comment