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);
}
这就是垃圾收集器正在收集的内容。
我有以下代码作为 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);
}
这就是垃圾收集器正在收集的内容。