在stackoverflow上可能有20个(或更多?)这些问题,但它们都没有解决我想要做的事情。
我有一个应用程序,其目的是通过Web服务从外部源接收一些数据,对其进行规范化,然后将其填充到BlockingCollection<T>
中,以便在以后连接到另一个Web时使用可以提供服务。接收数据的代码如下(它是Nancy回调):
private dynamic AcceptSignalData(dynamic parameters)
{
try
{
//This call extracts the post body data from the web request.
//The post body data contains JSON of the changed signals
var states = this.Bind< List< SignalStateData > >();
this._logger.Log(LogSeverity.Debug, string.Format("Received {0} states", states.Count));
foreach (var state in states.Select(s => new SignalStateData(s.Id, s.Value, s.Timestamp.ToUniversalTime())))
{
this._collection.Add(state);
}
return this.Response.AsJson(true);
}
catch (Exception ex)
{
this._logger.Log(LogSeverity.Error, "An error was thrown while extracting received data. The error is as follows:");
this._logger.Log(LogSeverity.Error, ex);
}
return this.Response.AsJson(false);
}
在这种情况下,如果可以建立与其他Web服务的连接,则会消耗this._collection
。
这样做的要求是:如果无法建立连接,应用程序应该只保留this._collection
中的数据,直到奶牛回家并在连接到达时发送。显然,如果等待很长时间,应用程序将抛出OutOfMemoryException
,这就是我遇到的问题。
我试图确定OutOfMemoryException
实际发生的点,这样我就可以从this._collection
中删除 n 最旧的项目。我想找到一个粗略的百分比,我的进程剩余多少内存。
我已经使用了this SO answer中的代码,但根据我的理解,这是系统中可用的总内存,这对我的目的来说并不是很有用。这是我现在的代码,但由于PerformanceCounter
的系统范围,它产生负数:
/// <summary>
/// The constructor for the <see cref="MemoryManager" /> object.
/// </summary>
public MemoryManager(ILogger logger)
{
this._memoryCounter = new PerformanceCounter("Memory", "Available Bytes");
this._memoryCancellationToken = new CancellationTokenSource();
this._updateMemoryTask = Task.Factory.StartNew(this.UpdateAvailableMemory, this._memoryCancellationToken.Token);
this._currentProcess = Process.GetCurrentProcess();
this._logger = logger;
this.AvailableMemoryPercentage = 100.0F;
}
#endregion
#region Methods
private async void UpdateAvailableMemory(object state)
{
var token = (CancellationToken)state;
while (!token.IsCancellationRequested)
{
try
{
float totalAvailableBytes = this._memoryCounter.NextValue();
float totalUsedBytes = totalAvailableBytes - this._currentProcess.PrivateMemorySize64;
this.AvailableMemoryPercentage = Math.Round(totalUsedBytes / totalAvailableBytes * 100, 2);
var logMessage = string.Format("RAM: {0} MB ({1}%)",
(1.0 * totalUsedBytes / 1024 / 1024).ToString("0.##"),
this.AvailableMemoryPercentage);
this._logger.Log(LogSeverity.Info, logMessage);
await Task.Delay(MEMORYCHECKINTERVAL_MS, token);
}
catch (Exception ex)
{
this._logger.Log(LogSeverity.Debug, "Exception in memory management:");
this._logger.Log(LogSeverity.Debug, ex);
}
}
}
我不关心我的过程使用了多少内存(好吧,我想我这样做但是它只占问题的50%);我对可用的数量更感兴趣。我知道这有很多不同的角度,但我正在寻找非常粗略估计。