首页 > 解决方案 > C#垃圾收集的原因?

问题描述

我有以下代码作为 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 多毫秒才能完成。

谢谢!

工作中的垃圾收集

标签: c#wpfjson.netgarbage-collection

解决方案


JArray.operator[]由于typeJToken是参考类,因此您在每个刻度上创建 300k 个对象。您为三个数组中的每一个中的每个项目都分配了双打,这隐式地创建了JValue实例:

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

这就是垃圾收集器正在收集的东西。


推荐阅读