我如何检查并告诉用户是否没有更多的内存剩余
本文关键字:是否 内存 用户 何检查 检查 | 更新日期: 2023-09-27 18:17:37
问题是有时我的程序占用大量内存并崩溃。相反,我需要以某种方式提醒或告诉用户,当他们达到内存限制或内存限制达到100%时,做一些除了崩溃之外的事情。
我使用ffmpeg.exe,占用大量内存。
private void beginOperationToolStripMenuItem_Click(object sender, EventArgs e)
{
svrNotifyIcon.Icon = Properties.Resources.Icons_Land_Play_Stop_Pause_Record_Normal;
changeFileNameToolStripMenuItem.Enabled = false;
beginOperationToolStripMenuItem.Enabled = false;
if (File.Exists(fullDefaultDirectory))
{
File.Delete(fullDefaultDirectory);
}
ffmp.Start(fullDefaultDirectory, 25);//"test.avi", @"d:'", 25);
timer1.Enabled = true;
startStop = true;
}
ffmp。从我的新班级开始:
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using DannyGeneral;
namespace ScreenVideoRecorder
{
class Ffmpeg
{
NamedPipeServerStream p;
String pipename = "mytestpipe";
byte[] b;
System.Diagnostics.Process process;
string ffmpegFileName = "ffmpeg.exe";
string workingDirectory;
public Ffmpeg()
{
workingDirectory = Path.GetDirectoryName(Application.ExecutablePath);//System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);//Application.StartupPath; //Path.GetDirectoryName(Application.ExecutablePath);// +@"'workingDirectory";
Logger.Write("workingDirectory: " + workingDirectory);
if (!Directory.Exists(workingDirectory))
{
Directory.CreateDirectory(workingDirectory);
}
ffmpegFileName = Path.Combine(workingDirectory, ffmpegFileName);//@"'ffmpeg.exe";
Logger.Write("FfmpegFilename: " + ffmpegFileName);
}
public void Start(string pathFileName, int BitmapRate)
{
try
{
string outPath = pathFileName;
Logger.Write("Output Video File Directory: " + outPath);
Logger.Write("Frame Rate: " + BitmapRate.ToString());
p = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte);
b = new byte[1920 * 1080 * 3]; // some buffer for the r g and b of pixels of an image of size 720p
ProcessStartInfo psi = new ProcessStartInfo();
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.FileName = ffmpegFileName;
Logger.Write("psi.FileName: " + psi.FileName);
psi.WorkingDirectory = workingDirectory;
Logger.Write("psi.WorkingDirectory: " + psi.WorkingDirectory);
psi.Arguments = @"-f rawvideo -pix_fmt bgr0 -video_size 1920x1080 -i ''.'pipe'mytestpipe -map 0 -c:v libx264 -r " + BitmapRate + " " + outPath;
Logger.Write("ProcessStartInfo Arguments" + @"-f rawvideo -pix_fmt bgr0 -video_size 1920x1080 -i ''.'pipe'mytestpipe -map 0 -c:v libx264 -r " + BitmapRate + " " + outPath);
//psi.RedirectStandardOutput = true;
process = Process.Start(psi);
process.EnableRaisingEvents = false;
p.WaitForConnection();
}
catch (Exception err)
{
Logger.Write("Exception Error: " + err.ToString());
}
}
public void PushFrame(Bitmap bmp)
{
try
{
int length;
// Lock the bitmap's bits.
//bmp = new Bitmap(1920, 1080);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
//Rectangle rect = new Rectangle(0, 0, 1280, 720);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
bmp.PixelFormat);
int absStride = Math.Abs(bmpData.Stride);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
//length = 3 * bmp.Width * bmp.Height;
length = absStride * bmpData.Height;
byte[] rgbValues = new byte[length];
//Marshal.Copy(ptr, rgbValues, 0, length);
int j = bmp.Height - 1;
for (int i = 0; i < bmp.Height; i++)
{
IntPtr pointer = new IntPtr(bmpData.Scan0.ToInt32() + (bmpData.Stride * j));
System.Runtime.InteropServices.Marshal.Copy(pointer, rgbValues, absStride * (bmp.Height - i - 1), absStride);
j--;
}
p.Write(rgbValues, 0, length);
bmp.UnlockBits(bmpData);
}
catch(Exception err)
{
Logger.Write("Error: " + err.ToString());
}
问题是,每40毫秒将内存中的位图发送到管道会占用大量内存或cpu使用率。
所以我想向用户抛出一个消息,让他达到限制,然后停止程序或其他事情,以防止它崩溃
这种事情很难有效地做到。
然而,你可能有一些运气,GC.RegisterForFullGCNotification()
至少会让你的代码知道什么时候完全GC接近。
详细信息请参考本文档:http://msdn.microsoft.com/en-us/library/cc713687.aspx
然而,我必须指出,这种事情很少奏效。