根据我的经验,似乎大多数人会告诉你强制垃圾收集是不明智的,但在某些情况下,你正在使用大型对象,这些对象并不总是在0代收集,但内存是一个问题,是它可以强制收集?这样做有最好的做法吗?
阅读这篇古老但经典的文档编写高性能托管应用程序 - 入门,我发现了以下声明
GC是自我调整的,可根据应用程序内存要求进行自我调整.在大多数情况下,以编程方式调用GC将阻碍调整.通过调用GC.Collect"帮助"GC很可能无法提高应用程序性能
我正在处理在给定时间点内消耗大量内存的应用程序.当我在使用该内存的代码中完成时,我正在调用GC.Collect.如果我不这样做,我会出现内存异常.这种行为是不一致的,但在30%的时间里,我得到了一个内存不足.添加GC.Collect后,我从来没有得到这个内存不足的异常.即使这个最佳实践文件提出反对建议,我的行动是否合理?
请考虑以下代码:
using System;
namespace memoryEater
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("alloc 1");
var big1 = new BigObject();
Console.WriteLine("alloc 2");
var big2 = new BigObject();
Console.WriteLine("null 1");
big1 = null;
//GC.Collect();
Console.WriteLine("alloc3");
big1 = new BigObject();
Console.WriteLine("done");
Console.Read();
}
}
public class BigObject
{
private const uint OneMeg = 1024 * 1024;
private static int _idCnt;
private readonly int _myId;
private byte[][] _bigArray;
public BigObject()
{
_myId = _idCnt++;
Console.WriteLine("BigObject {0} creating... ", _myId);
_bigArray …Run Code Online (Sandbox Code Playgroud) 我的任务是改进一段代码,以任何我认为合适的方式生成大量报告.
生成了大约10个相同的报告(对于数据库的每个"部分"),它们的代码与此类似:
GeneratePurchaseReport(Country.France, ProductType.Chair);
GC.Collect();
GeneratePurchaseReport(Country.France, ProductType.Table);
GC.Collect();
GeneratePurchaseReport(Country.Italy, ProductType.Chair);
GC.Collect();
GeneratePurchaseReport(Country.Italy, ProductType.Table);
GC.Collect();
Run Code Online (Sandbox Code Playgroud)
如果我删除这些GC.Collect()呼叫,报告服务将崩溃OutOfMemoryException.
大部分内存保存在一个List<T>内部,GeneratePurchaseReport并且一旦退出就不再使用 - 这就是为什么完整的GC集合将回收内存.
我的问题是双重的:
GeneratePurchaseReport它应该在崩溃和刻录之前进行完整的收集,不应该吗?我一直试图在我的应用程序中修复内存泄漏.几个月前,我注意到在我的应用程序中,超过95%的对象被提升为Gen2; 我有一些非常基本的问题,我在书中找不到.我希望你们能帮助我:
先感谢您.
我无法理解这里泄漏的是什么
using GDI = System.Drawing;
public partial class MainWindow : Window
{
[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr obj);
public MainWindow()
{
InitializeComponent();
var timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(50) };
timer.Tick += (s, a) =>
{
using (var bitmap = new GDI.Bitmap(1000, 1000))
{
var hbitmap = bitmap.GetHbitmap();
var image = Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
image.Freeze();
DeleteObject(hbitmap);
}
};
timer.Start();
}
Run Code Online (Sandbox Code Playgroud)
bitmap?弃置.hbitmap?删除.image?冷冻,但事实并非如此IDisposable.
事实是,这个应用程序会崩溃(在运行约20秒后在我的电脑上)
System.Drawing.dll中发生了未处理的"System.OutOfMemoryException"类型异常
附加信息:内存不足.
有任何想法吗?