簡體   English   中英

C#錯誤:System.Drawing.dll中發生了類型為'System.OutOfMemoryException'的未處理異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM