矩阵出现内存不足异常

9

这段简单的代码(一个10 000 * 10 000的矩阵相乘)会出现"System.OutOfMemoryException"异常:

#time

#r "Microsoft.Office.Interop.Excel"
#r "FSharp.PowerPack.dll"

open System
open System.IO

open Microsoft.FSharp.Math
open System.Collections.Generic


let mutable Matrix1 = Matrix.create 10000 10000 0.

let matrix4 = Matrix1 * Matrix1

我有以下错误:
System.OutOfMemoryException: An exception 'System.OutOfMemoryException' has been raised
   Microsoft.FSharp.Collections.Array2DModule.ZeroCreate[T](Int32 length1, Int32 length2)
   Microsoft.FSharp.Math.DoubleImpl.mulDenseMatrixDS(DenseMatrix`1 a, DenseMatrix`1 b)
   Microsoft.FSharp.Math.SpecializedGenericImpl.mulM[a](Matrix`1 a, Matrix`1 b)
   <StartupCode$FSI_0004>.$FSI_0004.main@() dans C:\Users\XXXXXXX\documents\visual studio 2010\Projects\Library1\Library1\Module1.fs:line 92
Stop due to an error

我有两个问题:

  1. 我的电脑上有8 GB的内存,根据我的计算,一个10 000 * 10 000的矩阵应该只占用381 MB。计算方法如下:10 000 * 10 000 = 100 000 000 个32位整型数字,共占用 100 000 000 * 4 bytes = 400 000 000。转换为MB, 即 400 000 000 / (1024*1024) = 381 MB。因此,我不理解为什么会出现“OutOfMemoryException”错误。

  2. 更一般地说(我认为这里不是这种情况),我感觉 F# interactive 会注册所有数据,从而导致内存负载过高。你知道有没有一种方式可以在不退出 F# 的情况下释放 F# interactive 注册的所有数据?


9
你的机器有任意量的内存;请记住,磁盘空间也是内存。RAM芯片只是一种缓存磁盘内存的快速方式。你可以拥有8GB、0.5GB或1000GB的物理内存;这完全无关紧要。你遇到的内存不足问题与你拥有多少RAM或磁盘空间无关,而是与每个进程的虚拟地址空间有关。 - Eric Lippert
2个回答

14

总之,fsi一个32位进程,最多可以容纳2GB的数据。将测试作为64位Windows应用程序运行,可以增加矩阵的大小,但仍然有.NET对象的2GB限制

我稍微纠正了一下你的计算。 Matrix1 是一个float矩阵,因此每个元素在内存中占用8个字节。 Matrix1matrix4 在内存中的总大小至少为:

2 * 10000 * 10000 * 8 = 1 600 000 000 bytes ~ 1.6 GB

(忽略matrix中的一些簿记部分)

所以在这种情况下,当fsi*32耗尽内存时也就不足为奇了。

将测试作为64位Windows进程执行,可以创建大小约为15000但不超过该大小的float矩阵。请查看这篇信息丰富的文章,其中给出了具有不同类型矩阵元素的具体数字。


这里有一篇文章讲解如何将fsi作为64位进程运行:http://ig2600.blogspot.com/2010/05/making-fsharp-interpreter-fsi-run-in.html 或者,您可以编译您的F#代码,默认情况下它会在64位操作系统上以64位进程运行。 - Robert

9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接