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