我很开心!:) 最近我玩了一个主题问题 - 尝试使用数据库解决它,但发现这种方式远非完美。矩阵 [20000,20000] 被实现为单个表。即使正确设置了索引,仅在我的 PC 上创建超过 4 亿条记录所需的时间也约为 1 小时。这对我来说并不重要。然后我运行算法来处理该矩阵(需要两次才能加入同一张表!),在它工作了半个多小时后,它甚至没有一步。在那之后,我明白唯一的方法是找到一种方法,只在内存中使用这样的矩阵,然后再次回到 C#。
我创建了试点应用程序来测试内存分配过程并确定使用不同结构的分配过程到底在哪里停止。
正如我在第一篇文章中所说,在 32 位 WinXP 下,使用 2-dim 数组仅分配大约650MB是可能的。使用 Win7 和 64 位编译后的结果也很可悲——不到700MB。
我使用了 JAGGED ARRAYS [][] 而不是单个二维数组 [,],您可以在下面看到结果:
在发布模式下编译为 32 位应用程序 - WinXP 32 位 3GB phys。内存。- 1.45GB
在发布模式下编译为 64 位应用程序 - Win7 64 位 2GB 在 VM 下 - 7.5GB
--我用于测试的应用程序来源附在这篇文章中。我在这里找不到如何附加源文件,所以只描述设计部分并将手动代码放在这里。创建 WinForms 应用程序。使用默认名称放置此类控件:1 个按钮、1 个 numericUpDown 和 1 个列表框 在 .cs 文件中添加下一个代码并运行。
private void button1_Click(object sender, EventArgs e)
{
//Log(string.Format("Memory used before collection: {0}", GC.GetTotalMemory(false)));
GC.Collect();
//Log(string.Format("Memory used after collection: {0}", GC.GetTotalMemory(true)));
listBox1.Items.Clear();
if (string.IsNullOrEmpty(numericUpDown1.Text )) {
Log("Enter integer value");
}else{
int val = (int) numericUpDown1.Value;
Log(TryAllocate(val));
}
}
/// <summary>
/// Memory Test method
/// </summary>
/// <param name="rowLen">in MB</param>
private IEnumerable<string> TryAllocate(int rowLen) {
var r = new List<string>();
r.Add ( string.Format("Allocating using jagged array with overall size (MB) = {0}", ((long)rowLen*rowLen*Marshal.SizeOf(typeof(int))) >> 20) );
try {
var ar = new int[rowLen][];
for (int i = 0; i < ar.Length; i++) {
try {
ar[i] = new int[rowLen];
}
catch (Exception e) {
r.Add ( string.Format("Unable to allocate memory on step {0}. Allocated {1} MB", i
, ((long)rowLen*i*Marshal.SizeOf(typeof(int))) >> 20 ));
break;
}
}
r.Add("Memory was successfully allocated");
}
catch (Exception e) {
r.Add(e.Message + e.StackTrace);
}
return r;
}
#region Logging
private void Log(string s) {
listBox1.Items.Add(s);
}
private void Log(IEnumerable<string> s)
{
if (s != null) {
foreach (var ss in s) {
listBox1.Items.Add ( ss );
}
}
}
#endregion
问题为我解决了。伙计们,提前谢谢你们!