mez*_*hic 8 .net c# memory performance memory-management
希望这是一个有效的帖子,它是C#问题和硬件的结合.
我正在对我们的服务器进行基准测试,因为我们发现了定量库的性能问题(用C#编写).我用一些简单的C#代码模拟了相同的性能问题 - 执行非常繁重的内存使用.
下面的代码是一个从线程池产生的函数,最多32个线程(因为我们的服务器有4个CPU x 8个核心).
这一切都在.Net 3.5上
问题是我们的性能差异很大.我运行以下功能1000次.代码运行所需的平均时间可能是3.5秒,但最快的只有1.2秒,而最慢的将是7秒 - 完全相同的功能!
我已经根据时间绘制了内存使用情况,并且似乎与GC没有任何关联.
我注意到的一件事是,当在一个线程中运行时,时间是相同的,没有疯狂的偏差.我还测试了CPU绑定算法,时序也相同.这让我们想知道内存总线是否无法应对.
我想知道这可能是另一个.net或C#问题,还是与我们的硬件有关?如果我使用过C++或Java,这会是同样的经历吗?我们使用4x Intel x7550和32GB内存.一般来说这个问题有什么办法吗?
Stopwatch watch = new Stopwatch();
watch.Start();
List<byte> list1 = new List<byte>();
List<byte> list2 = new List<byte>();
List<byte> list3 = new List<byte>();
int Size1 = 10000000;
int Size2 = 2 * Size1;
int Size3 = Size1;
for (int i = 0; i < Size1; i++)
{
list1.Add(57);
}
for (int i = 0; i < Size2; i = i + 2)
{
list2.Add(56);
}
for (int i = 0; i < Size3; i++)
{
byte temp = list1.ElementAt(i);
byte temp2 = list2.ElementAt(i);
list3.Add(temp);
list2[i] = temp;
list1[i] = temp2;
}
watch.Stop();
Run Code Online (Sandbox Code Playgroud)
(代码只是为了强调内存)
我会包含线程池代码,但我们使用了非标准的线程池库.
编辑:我已将"size1"减少到100000,基本上没有使用太多内存,我仍然会得到很多抖动.这表明它不是传输的内存量,而是记忆的频率?
小智 0
List内部使用数组来存储。我相信每次达到列表中可用空间的限制时,它都会尝试将数组的大小加倍。
当您进入循环时,随着列表的增长,它需要越来越大的连续内存块来分配新数组。通过一个线程,这非常容易。对于 2 个以上的线程,您正在争夺大块的连续内存。当数组变得更大并且连续内存更难找到时,它会随机触发 GC。