C# 下载时内存优化

C# 下载时内存优化,c#,optimization,C#,Optimization,大家好,我有下面的代码,我期待着优化,因为我消耗大量内存,这个例程被大量使用 第一个优化是将stringbuilder构造移出下载例程,并使其成为类的一个字段,然后在例程中清除它 你能建议其他的优化方法吗?或者告诉我一些可以帮助我的资源的方向(网络文章、书籍等) 我正在考虑用一个固定(更大)大小的缓冲区取代stringbuilder。。。或者创建一个更大尺寸的stringbuilder 提前谢谢 StreamWriter\u writer; 流阅读器(StreamReader);; 公共字符串下

大家好,我有下面的代码,我期待着优化,因为我消耗大量内存,这个例程被大量使用

第一个优化是将stringbuilder构造移出下载例程,并使其成为类的一个字段,然后在例程中清除它

你能建议其他的优化方法吗?或者告诉我一些可以帮助我的资源的方向(网络文章、书籍等)

我正在考虑用一个固定(更大)大小的缓冲区取代stringbuilder。。。或者创建一个更大尺寸的stringbuilder

提前谢谢

StreamWriter\u writer;
流阅读器(StreamReader);;
公共字符串下载(字符串msgId)
{
_作者:WriteLine(“主体”);
字符串响应=_reader.ReadLine();
如果(!response.StartsWith(“222”))
返回null;
bool done=false;
StringBuilder主体=新的StringBuilder(256*1024);
做
{
响应=_reader.ReadLine();
if(OnProgress!=null)
OnProgress(响应长度);
如果(响应==”)
{
完成=正确;
}
其他的
{
if(response.StartsWith(“…”))
response=response.Remove(0,1);
追加(应答);
body.Append(“\r\n”);
}
}而(!完成);
返回body.ToString();
}

使用固定大小的缓冲区实际上会使问题变得更糟,因为您必须选择一个比您可能填充的大小更大的缓冲区。每次都会重新创建这个缓冲区——或者如果您将它移到方法之外,每次创建类时都会重新创建这个缓冲区。如果将它作为类属性保留,那么它将与类的寿命一样长,而不仅仅是方法执行的时间长度


只要您需要以字符串形式返回结果,我就坚持使用StringBuilder。我唯一能想到的另一个选择是将它改为使用过滤流。也就是说,创建一个StreamReader,它环绕您当前使用的阅读器,并以下载方法相同的方式转换底层流。然后,消费类可以简单地使用StreamReader实现,您只需处理每个块,而不必一次将整个内容保存在内存中。如果消费类需要全部内容,这对您没有多大帮助,但我不知道您是如何使用它的。

仅在该方法的上下文中很难提出建议,因为结果值是一个包含所接收数据全部内容的字符串。。。不管此方法收集数据的时间长短,都需要将其转换为单个字符数组

也许值得问一个问题,这个方法的调用方是否真的需要在内存中一次调用整个响应;调用者是否可以一次处理一行数据,以便一次只需要在内存中存储一行?(如果是这样,使用
yield
语句实现的
IEnumerable
可能会工作得更好,而不会显著改变方法的实现)

关于内存分配,请记住并非所有的内存分配都是在.NET中创建的;大小超过85kb的分配会受到不同的对待,频繁分配/释放会导致内存碎片;见:

如果碎片化是您的主要问题,并且您一次只处理一个文档,那么创建一个共享缓冲区并保持其分配可以帮助您解决这一问题,但在假设这是您的问题之前,请检查这是否是您的问题。。。修复未损坏的东西是浪费时间。

使用系统;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace iGEENIESU_MemoryOptimization
{
    public partial class iGEENIEMemoryOptimize : Form
    {
        public iGEENIEMemoryOptimize()
        {
            InitializeComponent();
        }


        [StructLayout(LayoutKind.Sequential)]
        internal class MEMORYSTATUS
        {
            internal int length;
            internal int memoryLoad;
            internal uint totalPhys;
            internal uint availPhys;
            internal uint totalPageFile;
            internal uint availPageFile;
            internal uint totalVirtual;
            internal uint availVirtual;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern bool GlobalMemoryStatus(MEMORYSTATUS buffer);

        internal bool bLoop;

        private void iGEENIEMemoryOptimize_Load(object sender, EventArgs e)
        {
            bLoop = true;
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = false;
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

            backgroundWorker1.RunWorkerAsync();
            backgroundWorker2.RunWorkerAsync();

        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

           // MessageBox.Show("Ting Choo Chiaw has optimize your memory, have fun");
            Application.Exit();
        }

        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.pbmemoryoptimiz.Value = e.ProgressPercentage;
        }

        void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            int iCount = 0;
            while (iCount<10)
            {

                iCount++;
                this.backgroundWorker1.ReportProgress(iCount, null);
                System.Threading.Thread.Sleep(1000);

            }
            bLoop = false;
        }

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            MEMORYSTATUS status = new MEMORYSTATUS();

            GlobalMemoryStatus(status);

            int mem = (int)status.totalPhys;

            byte[] src = null;
            bool bContinue = true;
            do
            {
                try
                {
                    src = new byte[mem];
                    int len = src.Length;

                    while (true && bLoop)
                    {
                        len--;
                        if (len <= 0)
                            return;

                        src[len] = 0;
                    }

                    bContinue = false;
                }
                catch (OutOfMemoryException)
                {
                    mem = (int)((double)mem * 0.99);
                }

            } while (bContinue);
            backgroundWorker1.ReportProgress(10);
            if (backgroundWorker2 != null)
                if (backgroundWorker2.IsBusy)
                    backgroundWorker2.CancelAsync();
            src = null; // free resources instancely

            GC.Collect();
            GC.GetTotalMemory(false);
            GC.Collect();
        }
    }
}
使用System.Collections.Generic; 使用系统组件模型; 使用系统数据; 使用系统图; 使用System.Linq; 使用系统文本; 使用System.Windows.Forms; 使用System.Runtime.InteropServices; 命名空间IGeneisu_内存优化 { 公共部分类IGEENIEMORYOPTIMIZE:表单 { 公共IGeneimemoryoOptimize() { 初始化组件(); } [StructLayout(LayoutKind.Sequential)] 内部类内存状态 { 内部整数长度; 内部内存加载; 全物理内部单元; 内部有效单元; 内部uint totalPageFile; 内部uint可用文件; 内部单元总体虚拟; 内部单元有效虚拟; } [DllImport(“kernel32.dll”,SetLastError=true)] 内部静态外部布尔全局内存状态(MEMORYSTATUS缓冲区); 内部bool-bLoop; 私有void IgeenieMoryoOptimize_加载(对象发送方,事件参数e) { bLoop=true; backgroundWorker1.WorkerReportsProgress=true; backgroundWorker1.WorkerSupportsScanCellation=false; backgroundWorker1.ProgressChanged+=新的ProgressChangedEventHandler(backgroundWorker1\u ProgressChanged); backgroundWorker1.DoWork+=新的DoWorkerVenthandler(backgroundWorker1_DoWork); backgroundWorker2.DoWork+=新的Doworker2\u DoWork(backgroundWorker2\u DoWork); backgroundWorker1.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(backgroundWorker1\U RunWorkerCompleted); backgroundWorker1.RunWorkerAsync(); backgroundWorker2.RunWorkerAsync(); } void backgroundWorker1\u RunWorkerCompleted(对象发送方,runworkercompletedeventarge) { //MessageBox.Show(“Ting Choo Chiaw优化了你的记忆,玩得开心”); Application.Exit(); } void backgroundWorker1\u ProgressChanged(对象发送方,ProgressChangedEventArgs e) { this.pbmemoryoptimiz.Value=e.ProgressPercentag
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace iGEENIESU_MemoryOptimization
{
    public partial class iGEENIEMemoryOptimize : Form
    {
        public iGEENIEMemoryOptimize()
        {
            InitializeComponent();
        }


        [StructLayout(LayoutKind.Sequential)]
        internal class MEMORYSTATUS
        {
            internal int length;
            internal int memoryLoad;
            internal uint totalPhys;
            internal uint availPhys;
            internal uint totalPageFile;
            internal uint availPageFile;
            internal uint totalVirtual;
            internal uint availVirtual;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern bool GlobalMemoryStatus(MEMORYSTATUS buffer);

        internal bool bLoop;

        private void iGEENIEMemoryOptimize_Load(object sender, EventArgs e)
        {
            bLoop = true;
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = false;
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

            backgroundWorker1.RunWorkerAsync();
            backgroundWorker2.RunWorkerAsync();

        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

           // MessageBox.Show("Ting Choo Chiaw has optimize your memory, have fun");
            Application.Exit();
        }

        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.pbmemoryoptimiz.Value = e.ProgressPercentage;
        }

        void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            int iCount = 0;
            while (iCount<10)
            {

                iCount++;
                this.backgroundWorker1.ReportProgress(iCount, null);
                System.Threading.Thread.Sleep(1000);

            }
            bLoop = false;
        }

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            MEMORYSTATUS status = new MEMORYSTATUS();

            GlobalMemoryStatus(status);

            int mem = (int)status.totalPhys;

            byte[] src = null;
            bool bContinue = true;
            do
            {
                try
                {
                    src = new byte[mem];
                    int len = src.Length;

                    while (true && bLoop)
                    {
                        len--;
                        if (len <= 0)
                            return;

                        src[len] = 0;
                    }

                    bContinue = false;
                }
                catch (OutOfMemoryException)
                {
                    mem = (int)((double)mem * 0.99);
                }

            } while (bContinue);
            backgroundWorker1.ReportProgress(10);
            if (backgroundWorker2 != null)
                if (backgroundWorker2.IsBusy)
                    backgroundWorker2.CancelAsync();
            src = null; // free resources instancely

            GC.Collect();
            GC.GetTotalMemory(false);
            GC.Collect();
        }
    }
}