C#垃圾收集的原因?

C# garbage collecting reasons?

我有以下代码作为 WPF 应用程序。

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace TestLeak {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();

            Random RND = new Random();

            int SIZE = 100000;

            double fValue0 = 0;
            double fValue1 = 0;
            double fValue2 = 0;

            JArray aValues0 = new JArray(new double[SIZE]);
            JArray aValues1 = new JArray(new double[SIZE]);
            JArray aValues2 = new JArray(new double[SIZE]);
            JArray aValues = new JArray();
            aValues.Add(aValues0);
            aValues.Add(aValues1);
            aValues.Add(aValues2);

            DispatcherTimer oTimer = new DispatcherTimer(DispatcherPriority.Normal);
            oTimer.Tick += new EventHandler((oSender, aArgs) => {
                for (int i = 0; i < SIZE; i++) {
                    fValue0 += 1;
                    fValue1 += 1;
                    fValue2 += 1;
                    aValues0[i] = fValue0;
                    aValues1[i] = fValue1;
                    aValues2[i] = fValue2;
                }
            });
            oTimer.Interval = TimeSpan.FromMilliseconds(1000);
            oTimer.Start();
        }
    }
}

我不知道为什么 GC 需要如此努力那么,它在收集什么?这只是基本的赋值和覆盖(某种)数组值。会不会是 NewtonSoft Jarray 对象的问题?

问题是,对于我的应用程序,间隔要小得多(目标为 ~16 毫秒),但在每个步骤中,单独的 GC 需要 40+ 毫秒才能完成。

谢谢!

Garbage Collection at work

您每个 tick 创建 300k 个对象,因为 JArray.operator[] 的类型是 JToken,它是一个引用 class。您正在为三个数组中的每一个的每个项目分配双打,这隐式创建 JValue 个实例:

    public static implicit operator JToken(double value)
    {
        return new JValue(value);
    }

这就是垃圾收集器正在收集的内容。