使用ram的C#应用​​程序无法清除

时间:2015-06-11 16:09:34

标签: c# memory-management

好的,我创建了一个应用程序,应用程序正在吃ram太多。

问题:

  • 在结算过程中,我处理了对象,但ram的使用情况并未下降
  • 我不知道,错误在哪里。

该计划如何运作

  • 开始
  • 用户按空格 - >屏幕捕获,裁剪和剪切到屏幕。
  • 用户按1 - >清除所有剪切的图像。

"空间"工作原理:

PictureBox frame = new PictureBox();
frame.Size = target.Size;
frame.SizeMode = PictureBoxSizeMode.CenterImage;
frame.Image = get_img();
frame.Location = new Point(mouse.X - (target.Width / 2), mouse.Y - (target.Height / 2));
this.Controls.Add(frame);
frame.BringToFront();
box.Add(frame);
go_transparant();

" 1"工作原理:

foreach(var i in box){
   this.Controls.Remove(i);
   i.Dispose();
}
box.Clear();
box = new List<PictureBox>();

get_img函数:

this.Visible = false;
using (Bitmap ss = new Bitmap(sc.CaptureScreen()))
{
    this.Visible = true;

    result = ss.Clone(new Rectangle(mouse.X - target.Width / 2, mouse.Y - target.Height / 2, target.Width, target.Height),
    ss.PixelFormat);

    return result;
}

go_transparant函数:

int wl = GetWindowLong(this.Handle, GWL.ExStyle);
wl = wl | 0x80000 | 0x20;
SetWindowLong(this.Handle, GWL.ExStyle, wl);
SetLayeredWindowAttributes(this.Handle, 0, 150, LWA.Alpha);
this.AllowTransparency = true;
this.TransparencyKey = Color.Violet;
this.BackColor = Color.Violet;

完整代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Gma.UserActivityMonitor;

namespace LoA_Tarrot_Helper
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public enum GWL
        {
            ExStyle = -20
        }

        public enum WS_EX
        {
            Transparent = 0x20,
            Layered = 0x80000
        }

        public enum LWA
        {
            ColorKey = 0x1,
            Alpha = 0x2
        }

        [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
        public static extern int GetWindowLong(IntPtr hWnd, GWL nIndex);

        [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
        public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, int dwNewLong);

        [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
        public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, LWA dwFlags);

        [DllImport("user32.dll", EntryPoint = "GetCursorPos")]
        public static extern bool GetCursorPos(ref Point lpPoint);

        private void go_transparant()
        {
            int wl = GetWindowLong(this.Handle, GWL.ExStyle);
            wl = wl | 0x80000 | 0x20;
            SetWindowLong(this.Handle, GWL.ExStyle, wl);
            SetLayeredWindowAttributes(this.Handle, 0, 150, LWA.Alpha);
            this.AllowTransparency = true;
            this.TransparencyKey = Color.Violet;
            this.BackColor = Color.Violet;
        }
        private void prepare() 
        {
            target.Multiline = true;
            target.Enabled = false;
            target.Size = new Size(80, 80);
            target.BackColor = Color.Violet;
            this.Controls.Add(target);

            this.WindowState = FormWindowState.Maximized;
            this.TopMost = true;
        }
        TextBox target = new TextBox();
        List<PictureBox> box = new List<PictureBox>();

        private void Form1_Load(object sender, EventArgs e)
        {
            prepare();
            go_transparant();
            timer1.Start();
            HookManager.KeyUp += HookManager_KeyUp;
        }
        ScreenCapture sc = new ScreenCapture();
        Bitmap result;
        private Bitmap get_img() 
        {
            this.Visible = false;
            using (Bitmap ss = new Bitmap(sc.CaptureScreen()))
            {
                this.Visible = true;
                //Graphics g3 = Graphics.FromImage(bmp);
                //g3.DrawImageUnscaled(ss, mouse.X-target.Width/2, mouse.Y-target.Height/2, target.Width, target.Height);

                /*Rectangle cropRect = new Rectangle(,);
                Bitmap src = Image.FromFile(fileName) as Bitmap;
                Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
                using (Graphics g = Graphics.FromImage(target))
                {
                    g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height),
                                     cropRect,
                                     GraphicsUnit.Pixel);
                }

                Graphics g2 = frame.CreateGraphics();
                g2.DrawImageUnscaled(bmp, 0, 0, target.Width, target.Height);*/


                result = ss.Clone(new Rectangle(mouse.X - target.Width / 2, mouse.Y - target.Height / 2, target.Width, target.Height),
                ss.PixelFormat);

                /*pictureBox1.Image = ss;
                pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;

                pictureBox2.Image = result;
                pictureBox2.SizeMode = PictureBoxSizeMode.Zoom;*/
                //ss.Dispose();
                return result;
            }
        }

        void HookManager_KeyUp(object sender, KeyEventArgs e)
        {
            try { 
                if (e.KeyCode == Keys.Space)
                {
                    PictureBox frame = new PictureBox();
                    frame.Size = target.Size;
                    frame.SizeMode = PictureBoxSizeMode.CenterImage;
                    frame.Image = get_img();
                    frame.Location = new Point(mouse.X - (target.Width / 2), mouse.Y - (target.Height / 2));
                    this.Controls.Add(frame);
                    frame.BringToFront();
                    box.Add(frame);
                    go_transparant();

                }
                if (e.KeyCode == Keys.D1) {
                    foreach(var i in box){
                        this.Controls.Remove(i);
                        i.Dispose();
                    }
                    box.Clear();
                    box = new List<PictureBox>();
                }
            }
            catch (Exception ex) { MessageBox.Show("ERROR: " + ex.Message);}
        }
        Point mouse = new Point();
        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                GetCursorPos(ref mouse);
                if (target != null)
                {
                    target.Location = new Point(mouse.X - target.Width / 2, mouse.Y - target.Height / 2);
                }
            }
            catch (Exception ex) { MessageBox.Show("ERROR: " + ex.Message); timer1.Stop(); timer1.Start(); }
        }

    }
}

2 个答案:

答案 0 :(得分:1)

即使您正在处理对象,内存也只会在垃圾收集器运行时实际释放。您可以通过运行以下代码来强制执行此操作:

GC.Collect();
GC.WaitForPendingFinalizers();

但是,不建议您自己这样做,因为垃圾收集器应该在最佳状态下运行。

为什么在处理对象时需要显式减少应用程序使用的内存?

答案 1 :(得分:0)

检查此帖子 How does C# manage memory allocated by a new operator inside a loop?

我的猜测是内存是由操作系统和/或垃圾收集器保留和管理的,并且取决于应用程序的使用情况,它可能会保留“保留”或被释放。

我们在这里开发了一个程序,它读取数百个XML并连接到SAP Business One,每天创建数百个事务。我们尽可能多地关闭连接和处理对象,但行为始终是相同的:程序从1mb的内存开始,但是一旦进程开始,它就会上升到1gb并且永远不会下降。

进程至少每24小时发生一次(有时它们会强制进程提前开始并在同一天执行2到3次)并且程序使用已经保留的内存,它不会消耗更多。