簡體   English   中英

是否可以使用反射修改 ReadOnlyCollection

[英]Is it possible to modify a ReadOnlyCollection using reflection

我正在處理一個 SDK,只要主連接對象在范圍內,它就會保留對它創建的每個對象的引用。 定期創建新的連接對象會導致其他資源問題,這不是一個選項。

為了做我需要做的事情,我必須遍歷數千個這些對象(幾乎 100,000 個),雖然我當然不會保留對這些對象的引用,但我使用的 SDK 中的對象模型會。 這會消耗內存並且非常接近於導致 OutOfMemoryExceptions。

這些對象存儲在嵌套的 ReadOnlyCollections 中,所以我現在正在嘗試的是,當我完成這些集合時,使用反射將其中一些集合設置為 null,以便垃圾收集器可以收集使用過的內存。

foreach (Build build in builds)
{
        BinaryFileCollection numBinaries = build.GetBinaries();
        foreach (BinaryFile binary in numBinaries)
        {
            this.CoveredBlocks += binary.HitBlockCount;
            this.TotalBlocks += binary.BlockCount;
            this.CoveredArcs += binary.HitArcCount;
            this.TotalArcs += binary.ArcCount;

            if (binary.HitBlockCount > 0)
            {
                this.CoveredSourceFiles++;
            }

            this.TotalSourceFiles++;

            foreach (Class coverageClass in binary.GetClasses())
            {
                if (coverageClass.HitBlockCount > 0)
                {
                    this.CoveredClasses++;
                }

                this.TotalClasses++;

                foreach (Function function in coverageClass.GetFunctions())
                {
                    if (function.HitBlockCount > 0)
                    {
                        this.CoveredFunctions++;
                    }

                    this.TotalFunctions++;
                }
            }

            FieldInfo fi = typeof(BinaryFile).GetField("classes", BindingFlags.NonPublic | BindingFlags.Instance);
            fi.SetValue(binary, null);
    }

當我檢查 numBinaries[0] 中類成員的值時,它返回 null,這似乎完成了任務,但是當我運行此代碼時,內存消耗只會不斷增加,就像我不這樣做時一樣快將類設置為空。

我想弄清楚的是,這種方法是否存在本質上的缺陷,或者是否有另一個對象保留了對我缺少的 ReadOnlyCollection 類的引用。

我可以想到幾個替代方案......

  1. 邏輯上把它分開。 您提到它“在連接期間”保留所有引用。 你能做 10%,關閉它,打開一個新的,跳過那 10%,再拿 10%(總共 20%)等等嗎?
  2. 我們在這里談論的是多少內存,這個工具是否會長期存在? 那么,如果它在幾分鍾內使用大量 RAM 呢? 你真的有 OOM 嗎? 如果您的系統有那么多可用 RAM 供程序使用,為什么不使用它呢? 您為 RAM 付費。 這讓我想起了 Raymond Chen 的一篇關於 100% CPU 消耗的博客文章
  3. 如果你真的想看看是什么阻止了垃圾收集,啟動 SOS 並使用!gcroot是一個開始。

但是盡管如此,如果這真的是一個問題,我會花更多的時間與 3rd 方 API 提供商合作——在某個時候他們可能會發布你想要的更新來打破這一點——你會回到原點,或者更糟糕的是,您可能會在產品中引入細微的錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM