在一段代码中暂停GC

罗南·蒂博道

有没有办法让一段代码完全搁置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而不是7GB的空间,所有临时对象均未进行GC处理,但是GC在整个批处理过程中仅运行了一次(一次!),而不是很多每秒多次(在更改Visual Studio中的GC视图之前,从GC触发的所有单个点看都是一条直线)。

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

除非有人发现如何增加段大小,以便我可以进一步扩大它,或者有更好的选择来完全停止GC(不仅是特定的一代,而且要全部停止),否则几天后我会接受我自己的答案。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

暂停CCNode一段时间

来自分类Dev

延迟一段代码

来自分类Dev

如何选择此代码中的第一段?

来自分类Dev

如何跟踪一段代码中变量的使用?

来自分类Dev

在php中单击按钮时触发一段代码

来自分类Dev

关闭C#中的一段代码使用的过程

来自分类Dev

不要在jQuery代码段中重复一段代码

来自分类Dev

OpenGL:将屏幕内容暂停一段时间

来自分类Dev

如何暂停 selenium 脚本的执行一段时间?

来自分类Dev

了解一段python代码

来自分类Dev

从数据部分执行一段代码

来自分类Dev

解释一段Haskell代码

来自分类Dev

等待函数的一段代码?

来自分类Dev

一段代码如何影响算法?

来自分类Dev

使javascript忽略一段代码

来自分类Dev

Matlab:了解一段代码

来自分类Dev

解释一段Haskell代码

来自分类Dev

一段JavaScript代码的说明

来自分类Dev

一段代码的索引OutOfBound异常?

来自分类Dev

理解一段代码的 Kotlin 问题

来自分类Dev

如何在IntelliJ IDEA中缩进/移动一行代码或一段代码

来自分类Dev

如何跳过一段代码并转到硒中的所需代码

来自分类Dev

如何区分字符串中的代码是一段JS还是CSS代码?

来自分类Dev

如何计划一段代码在Swift的下一个runloop中执行?

来自分类Dev

如何计划一段代码在Swift的下一个runloop中执行?

来自分类Dev

多次运行一段代码,以更改R中的某些参数(例如SAS中的宏)

来自分类Dev

在python中打印第一段

来自分类Dev

如何在Python中运行一段代码,类似于Matlab

来自分类常见问题

我如何在python 3.8中重复一段代码