【发布时间】:2014-02-10 06:49:01
【问题描述】:
我的应用存在大量内存泄漏,并且在运行 1 天后内存使用量从 40MB 飙升至 700MB。我正在使用 C# 进行编码,但我不知道如何阻止泄漏。我怀疑以下两个功能是罪魁祸首。
SendLiveVideo:它从相机捕获并通过套接字发送。
ResizeImage:为了节省带宽,它在通过套接字发送之前调整图像大小。
我的应用调用第 3 方库(LibImage, Libcapture) 从旧网络摄像头(4 个摄像头)捕获图像并将视频流式传输到 LAN 连接的客户端列表。
在 Sendvideo 函数退出时,我已经在 finally 语句中为我的 *variables 分配了 null 值以释放内存,但它似乎不起作用。
我需要使用 Dispose 方法吗?
this.timer_stream0.Interval = 30; /*I capture image and send to client this every 30 milseconds make it as video stream to human eye*/
this.timer_stream0.Tick += new System.EventHandler(this.timer_stream0_Tick);
private void timer_stream0_Tick(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(SendLiveVideo, 0);
ThreadPool.QueueUserWorkItem(SendLiveVideo, 1);
ThreadPool.QueueUserWorkItem(SendLiveVideo, 2);
ThreadPool.QueueUserWorkItem(SendLiveVideo, 3);
}
void SendLiveVideo(object state)
{
LibImage image=new LibImage();
LibCapture capture_camera=new LibCapture();
int cam = (int)state;
System.Collections.ArrayList m_workerSocketList_Video =
ArrayList.Synchronized(new System.Collections.ArrayList());
switch (cam)
{
case 0:
{
image = image0;
capture_camera = capture_camera0;
m_workerSocketList_Video = m_workerSocketList_Video0;
break;
}
case 1:
{
image = image1;
capture_camera = capture_camera1;
m_workerSocketList_Video = m_workerSocketList_Video1;
break;
}
case 2:
{
image = image2;
capture_camera = capture_camera2;
m_workerSocketList_Video = m_workerSocketList_Video2;
break;
}
default:
{
image = image3;
capture_camera = capture_camera3;
m_workerSocketList_Video = m_workerSocketList_Video3;
break;
}
}
byte[] imageData=new byte[1000 * 1000 * 10];
try
{
try
{
capture_camera.Capture(image);
}
catch
{
// objData = null;
imageData = null;
return;
}
imageData = image.SaveToMem(PNG);
var stream = new MemoryStream(imageData);
{
var bitmap = new Bitmap(stream);
bitmap = ResizeImage(bitmap, new Size(150, 112));
//stream = null;
MemoryStream streamnew = new MemoryStream();
bitmap.Save(streamnew, ImageFormat.Png);
imageData = streamnew.ToArray();
bitmap = null;
streamnew = null;
}
Socket workerSocket = null;
for (int i = 0; i < m_workerSocketList_Video.Count; i++)
{
workerSocket = (Socket)m_workerSocketList_Video[i];
if (workerSocket != null)
{
if (SocketConnected(workerSocket))
{
workerSocket.Send(imageData);
}
}
}
}
catch (SocketException se)
{
// MessageBox.Show(se.Message);
return;
}
finally
{
image = null;
capture_camera = null;
imageData = null;
m_workerSocketList_Video = null;
}
}
private Bitmap ResizeImage(Bitmap imgToResize, Size size)
{
try
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
b.SetResolution(200, 200);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighSpeed;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return b;
}
【问题讨论】:
-
为什么你的局部变量最后设置为null?您是否期望它释放资源,如果您在释放模式下运行且调试器分离设置这些空值将完全没有影响,因为编译器将尽快释放资源。
-
将局部变量设置为
null完全没有效果。您也可以在某处使用辅助数组private LibImage[] _image = new LibImage[] {_image0, image1, ... };,这样您就不需要开关、可重复代码和局部变量,只需使用_image[cam]。你知道this吗?
标签: c# memory-leaks