gpt4 book ai didi

c# - C# 应用程序内存泄漏?如何停止?

转载 作者:太空宇宙 更新时间:2023-11-03 13:28:02 25 4
gpt4 key购买 nike

我的应用程序有巨大的内存泄漏,内存使用量在运行 1 天后从40MB 飙升至 700MB。我正在用 C# 编码,但我不知道如何阻止泄漏。我怀疑以下 2 个函数是罪魁祸首。

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;
}

最佳答案

试着看看我的 SO 答案 here .

基本上,这是一种如何找到泄漏源的方法。
这实际上是一个复制粘贴:

  1. Open a memory profiler. I use perfmon. This article has some material about setting perfmon and @fmunkert also explains it rather well.
  2. Locate an area in the code that you suspect that it is likely that the leak is in that area. This part is mostly depending on you having good guesses about the part of the code that is responsible for the issue.
  3. Push the Leak to the extreme: Use labels and "goto" for isolating an area / function and repeat the suspicious code many times (a loop will work to. I find goto more convenient for this matter).
  4. In the loop I have used a breakpoint that halted every 50 hits for examining the delta in the memory usage. Of course you can change the value to feet a noticeable leak change in your application.
  5. If you have located the area that causes the leak, the memory usage should rapidly spike. If the Memory usage does not spike, repeat stages 1-4 with another area of code that you suspect being the root cause. If it does, continue to 6.
  6. In the area you have found to be the cause, use same technique (goto + labels) to zoom in and isolate smaller parts of the area until you find the source of the leak.

Note that the down sides of this method are:

  1. If you are allocating an object in the loop, it's disposal should be also contained in the loop.
  2. If you have more than one source of leak, It makes it harder to spot (yet still possible)

关于c# - C# 应用程序内存泄漏?如何停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21670703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com