gpt4 book ai didi

c# - 在一段代码中暂停 GC

转载 作者:可可西里 更新时间:2023-11-01 03:02:05 25 4
gpt4 key购买 nike

有没有办法让一段代码的GC完全搁置?我在其他类似问题中发现的唯一一件事是 GC.TryStartNoGCRegion,但它受限于您指定的内存量,它本身受限于临时段的大小。

有没有办法完全绕过它并告诉 .NET “分配你需要的任何东西,不要执行 GC 周期” 或增加段的大小?据我发现,它在多核服务器上最多为 1GB,这比我需要分配的要少,但我不希望 GC 发生(我有多达 TB 的可用 RAM,并且有数千个 GC 尖峰在那个部分,我非常乐意用 RAM 使用量的 10 倍甚至 100 倍来交换它们。

编辑:

既然有赏金,我认为如果我指定用例会更容易。我正在使用 LINQ to XML 将一个非常大的 XML 文件(目前为 1GB,很快将达到 12GB)加载并解析到内存中的对象中。我不是在寻找替代方案。我正在从数百万个 XElements 创建数百万个小对象,GC 试图不停地收集,而我很乐意让所有 RAM 用完。我有 100 GB 的 RAM,一旦使用了 4GB,GC 就会开始不停地收集,这对内存非常友好,但对性能不友好。我不关心内存,但我关心性能。我想采取相反的权衡。

虽然我不能在这里发布实际代码,但这里有一些非常接近最终代码的示例代码,可以帮助那些需要更多信息的人:

var items = XElement.Load("myfile.xml")
.Element("a")
.Elements("b") // There are about 2 to 5 million instances of "b"
.Select(pt => new
{
aa = pt.Element("aa"),
ab = pt.Element("ab"),
ac = pt.Element("ac"),
ad = pt.Element("ad"),
ae = pt.Element("ae")
})
.Select(pt => new
{
aa = new
{
aaa = double.Parse(pt.aa.Attribute("aaa").Value),
aab = double.Parse(pt.aa.Attribute("aab").Value),
aac = double.Parse(pt.aa.Attribute("aac").Value),
aad = double.Parse(pt.aa.Attribute("aad").Value),
aae = double.Parse(pt.aa.Attribute("aae").Value)
},
ab = new
{
aba = double.Parse(pt.aa.Attribute("aba").Value),
abb = double.Parse(pt.aa.Attribute("abb").Value),
abc = double.Parse(pt.aa.Attribute("abc").Value),
abd = double.Parse(pt.aa.Attribute("abd").Value),
abe = double.Parse(pt.aa.Attribute("abe").Value)
},
ac = new
{
aca = double.Parse(pt.aa.Attribute("aca").Value),
acb = double.Parse(pt.aa.Attribute("acb").Value),
acc = double.Parse(pt.aa.Attribute("acc").Value),
acd = double.Parse(pt.aa.Attribute("acd").Value),
ace = double.Parse(pt.aa.Attribute("ace").Value),
acf = double.Parse(pt.aa.Attribute("acf").Value),
acg = double.Parse(pt.aa.Attribute("acg").Value),
ach = double.Parse(pt.aa.Attribute("ach").Value)
},
ad1 = int.Parse(pt.ad.Attribute("ad1").Value),
ad2 = int.Parse(pt.ad.Attribute("ad2").Value),
ae = new double[]
{
double.Parse(pt.ae.Attribute("ae1").Value),
double.Parse(pt.ae.Attribute("ae2").Value),
double.Parse(pt.ae.Attribute("ae3").Value),
double.Parse(pt.ae.Attribute("ae4").Value),
double.Parse(pt.ae.Attribute("ae5").Value),
double.Parse(pt.ae.Attribute("ae6").Value),
double.Parse(pt.ae.Attribute("ae7").Value),
double.Parse(pt.ae.Attribute("ae8").Value),
double.Parse(pt.ae.Attribute("ae9").Value),
double.Parse(pt.ae.Attribute("ae10").Value),
double.Parse(pt.ae.Attribute("ae11").Value),
double.Parse(pt.ae.Attribute("ae12").Value),
double.Parse(pt.ae.Attribute("ae13").Value),
double.Parse(pt.ae.Attribute("ae14").Value),
double.Parse(pt.ae.Attribute("ae15").Value),
double.Parse(pt.ae.Attribute("ae16").Value),
double.Parse(pt.ae.Attribute("ae17").Value),
double.Parse(pt.ae.Attribute("ae18").Value),
double.Parse(pt.ae.Attribute("ae19").Value)
}
})
.ToArray();

最佳答案

目前我能找到的最好的方法是切换到具有更大段大小的服务器 GC(它本身没有改变),让我为没有 gc 部分使用更大的数字:

        GC.TryStartNoGCRegion(10000000000); // On Workstation GC this crashed with a much lower number, on server GC this works

这违背了我的预期(这是 10GB,但根据我在在线文档中可以找到的内容,我当前设置中的段大小应该是 1 到 4GB,所以我预计参数无效)。

通过这个设置,我得到了我想要的东西(GC 暂停,我分配了 22GB 而不是 7,所有临时对象都没有被 GC,但是 GC 在整个批处理过程中运行一次(一次!)而不是每秒多次(在更改之前,visual studio 中的 GC View 看起来像一条直线,来自所有单独的 GC 触发点)。

这不是很好,因为它不会缩放(添加 0 会导致崩溃),但它比我目前发现的任何其他东西都要好。

除非有人发现如何增加段大小以便我可以进一步推进或有更好的选择来完全停止 GC(不仅是某一代而是所有代)我将接受我自己的答案几天。

关于c# - 在一段代码中暂停 GC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37262774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com