[英]An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Drawing.dll
[英]C# Error: An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Drawing.dll
一段時間以來,我已經在C#中使用pictureBox來為模擬和其他事情制作動畫。 現在,我正在編寫代碼來誘騙一個朋友(他只需要按alt-f4即可將其關閉,沒什么大不了的。)但我一直收到此錯誤:
An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Drawing.dll
Additional information: Out of memory.
碼:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EnrogSecurityBreach
{
public partial class Form1 : Form
{
Timer timer = new Timer();
Form1 form1;
//Bitmap bmp;
public Form1()
{
InitializeComponent();
form1 = this;
form1.TransparencyKey = Color.White;
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
pictureBox1.Left = 0;
pictureBox1.Top = 0;
pictureBox1.Width = Screen.PrimaryScreen.Bounds.Width;
pictureBox1.Height = Screen.PrimaryScreen.Bounds.Height;
timer.Enabled = true;
timer.Interval = 10;
timer.Tick += timer_tick;
}
Random rand = new Random();
int partsection = 0;
int waitint = 0;
int ran1 = 0;
int ran2 = 0;
int intensifies = 0;
public void timer_tick(object e, EventArgs ea)
{
Bitmap bmp;
bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
if (partsection == -1)
{
}
else if (partsection<300)
{
if (waitint == 0)
{
ran1 = rand.Next(0, pictureBox1.Width);
ran2 = rand.Next(0, pictureBox1.Width);
waitint = 10;
}
else
{
waitint--;
}
g.FillRectangle(new SolidBrush(Color.Green), (float)ran1, (float)0, 3, pictureBox1.Height);
g.FillRectangle(new SolidBrush(Color.DarkGreen), (float)ran2, (float)0, 3, pictureBox1.Height);
partsection++;
}
else if (partsection < 1000)
{
if (intensifies < 255)
{
intensifies++;
}
else
{
}
g.FillRectangle(new SolidBrush(Color.FromArgb(intensifies,Color.Black)), (float)0, (float)0, pictureBox1.Width, pictureBox1.Height);
}
}
pictureBox1.Image = bmp;
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
感謝您的任何幫助。
您的位圖需要聲明為表單的實例變量。
編輯
具體來說,在類實例變量中取消注釋Bitmap
的聲明。 接下來,添加以下代碼:
protected override void OnResize(EventArgs e)
{
pictureBox1.Left = 0;
pictureBox1.Top = 0;
pictureBox1.Width = Screen.PrimaryScreen.Bounds.Width;
pictureBox1.Height = Screen.PrimaryScreen.Bounds.Height;
bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
base.OnResize(e);
}
為什么? 因為您需要在調整窗體大小時調整圖片框的大小,否則用戶將更改屏幕分辨率。 現在, Bitmap
僅聲明一次。 我將代碼運行了幾分鍾,沒有任何不良影響。
順便說一句, pictureBox1
調整大小的代碼已從構造函數中刪除。
發生這種情況的原因是,您使用的某些資源是非托管資源,並且您沒有將其置於using
塊之下,也沒有using
任何其他方式在使用后處置非托管資源。 因此,內存泄漏。
例如,這些行
g.FillRectangle(new SolidBrush(Color.Green), (float)ran1, (float)0, 3, pictureBox1.Height);
g.FillRectangle(new SolidBrush(Color.DarkGreen), (float)ran2, (float)0, 3, pictureBox1.Height);
可以更改為
using (SolidBrush greenBrush = new SolidBrush(Color.Green))
using (SolidBrush darkGreenBrush = new SolidBrush(Color.DarkGreen)) {
g.FillRectangle(greenBrush , (float)ran1, (float)0, 3, pictureBox1.Height);
g.FillRectangle(darkGreenBrush, (float)ran2, (float)0, 3, pictureBox1.Height);
}
同樣,這條線
g.FillRectangle(new SolidBrush(Color.FromArgb(intensifies,Color.Black)), (float)0, (float)0, pictureBox1.Width, pictureBox1.Height);
對此
using (SolidBrush blackBrush = new SolidBrush(Color.FromArgb(intensifies, Color.Black)))
g.FillRectangle(blackBrush, (float)0, (float)0, pictureBox1.Width, pictureBox1.Height);
另一個建議是,您應該檢查System.Drawing
上的非托管資源。 由於您可能會顯示更多但未被指出的非托管資源-或-您沒有提出問題,而是實際上在代碼的其他部分。
這是更多非托管資源:
這是有關Bitmap
導致泄漏的另一種解釋(由於小型托管Bitmap
類包裝器,由於垃圾收集器延遲觸發,可能導致內存不足),請參閱漢斯·帕桑特先生的解釋
@IronGeek找到了解決方案:
更改代碼以使用3840x2160的固定屏幕分辨率,對我來說確實會拋出OutOfMemoryException。 因此很明顯它確實泄漏了,盡管是由於延遲觸發了GC(請參閱下面的Ian答案)。 添加if(pictureBox1.Image!= null)pictureBox1.Image.Dispose(); 就在pictureBox1.Image = bmp之前; 可能會解決內存不足的問題...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.