处理OutOfMemory异常

时间:2015-06-02 21:57:41

标签: c# for-loop out-of-memory

在循环遍历大型列表并从该列表中添加对象时,是否有正确的方法来处理Out Of Memory Exceptions?这样做的正确方法是什么?我有一个大的Linq查询返回大约600K项目。然后我浏览每个项目并将其添加到对象中。代码如下。

  static void Main(string[] args)
    {
        GrabData();
    }

    public static void GrabData()
    {
        decimal? TotalNetClaim = 0;
        using (var Context = new VSCMeSnapEntities())
        {              
            List<DriveTimeObject> DataFile = new List<DriveTimeObject>(); 
            DriveTimeObject DT = new DriveTimeObject();
            DateTime ParamDate = new DateTime(2015, 05, 30);
            List<viewDriveTimeFileDump> DataQuery = new List<viewDriveTimeFileDump>();

            DataQuery = (from z in Context.viewDriveTimeFileDumps select z).ToList();

            foreach (var item in DataQuery)
            {
                decimal? AmountChargedParts = DT.GetAmountChargedParts(item.chrComponSts.Trim(), item.mnsTotalParts);
                decimal? AmountChargedPartsTax = DT.GetAmountChargedPartsTax(item.chrComponSts.Trim(), item.mnsTotalPartTax);
                decimal? AmountChargedLabor = DT.GetAmountChargedLabor(item.chrComponSts.Trim(), item.mnsTotalLabor);
                decimal? AmountChargedLaborTax = DT.GetAmountChargedLaborTax(item.chrComponSts.Trim(), item.mnsTotalLaborTax);
                int? DaysOut = DT.GetDaysOutClaim(item.intRepairFacilCode, item.dtmContPurchDate, item.dtmReported);
                long? MilesOut = DT.GetMilesOutClaim(item.intRepairFacilCode, item.inbIncurMiles, item.inbOrigMiles);
                decimal? deductible = DT.GetDeductible(item.chrContSts, item.mnsDeduct);
                decimal? netClaim = DT.GetNetClaim(item.chrComponSts.Trim(), item.mnsTotalParts, item.mnsTotalPartTax, item.mnsTotalLabor, item.mnsTotalLaborTax, item.mnsDeduct);

                DataFile.Add(new DriveTimeObject
                {
                    DealerNumber = item.chrDlrNum,
                    VSCName = item.chvVSCName,
                    IcLocationNumber = item.IcLocationNumber,
                    IcRegion = item.IcRegion,
                    Identifier = item.chrIdentifier,
                    ContractNumber = item.chrContNum,
                    VIN = item.chrVIN,
                    CoverageCode = item.CvgCode,
                    ClaimNum = item.intClaimNum,
                    OriginalMiles = item.inbOrigMiles,
                    ContractPurchaseDate = item.dtmContPurchDate,
                    IncurMiles = item.inbIncurMiles,
                    DateReported = item.dtmReported,
                    DaysOutClaim = DaysOut,
                    MilesOut = MilesOut,
                    RepairFacilityNumber = item.intRepairFacilCode,
                    FacilityName = item.chvFacilityName,
                    ZipFive = item.chrZipFive,
                    FacilityAdvisor = item.chrFacilAdvisor,
                    ComponentStatus = item.chrComponSts,
                    ComponentStatusWord = item.ComponDesc,
                    ComponentCode = item.chrComponCode,
                    StatusMasterDescription = item.MasterDesc,
                    ComponentDescription = item.chvComponDesc,
                    Parts = AmountChargedParts,
                    PartsTax = AmountChargedPartsTax,
                    Labor = AmountChargedLabor,
                    LaborTax = AmountChargedLaborTax,
                    Deductible = deductible,
                    NetClaim = netClaim,
                    CarrierCode = item.intCarrierCode,
                    NetworkStatus = item.NetworkStatus,
                    AddOn = item.chrAddOn,
                    ETCDate = item.ETC,
                    ATCDate = item.ATC,
                    LaborTime = item.reaLaborTime,
                    PaidDate = item.dtmPdDate,
                    PaymentID = item.intPaymentID,
                    BatchNumber = item.intBatchNum

                });

                TotalNetClaim += netClaim;
            }
            Context.Dispose();
        }

        Console.WriteLine(TotalNetClaim);
        Console.ReadKey();


    }

我在foreach循环期间内存不足,我想知道如何调整代码才能使其正常工作。

2 个答案:

答案 0 :(得分:1)

防止内存不足的方法是不要耗尽内存。这意味着您需要摆脱不需要的物体。

如果不了解更多用例,很难提出修复建议。无论如何,在内存中包含如此多的对象并使其耗尽并崩溃是不好的做法。 只保留您需要的内容。

一个解决方法是不使用RAM内存,而是使用硬盘内存。例如:您可以将这些对象写入数据库并删除它们,因此不要将它们保留在一起。考虑到你有600k对象,你可以批量生成10k / 25k记录。然后,当您需要对象时,可以查询它们。如果需要对所有对象进行计算,我建议使用SQL查询来执行这些操作。

答案 1 :(得分:0)

您正在创建新的DriveTimeObject并将其存储在名为List<DriveTimeObject>的{​​{1}}中。假设DataFile中有600k项,这意味着您的列表中还包含600k项。

但是,你根本就没有使用那个列表,所以它无缘无故地咀嚼你所有的记忆。删除它并节省一整吨内存,它也应该运行得更快。