.net 优化查询以提高内存使用率:OutOfMemory异常
我有一个控制台应用程序,可以连接到远程数据库并运行多个查询 我正在使用64位F#构建应用程序。我对这条路充满信心.net 优化查询以提高内存使用率:OutOfMemory异常,.net,f#,.net,F#,我有一个控制台应用程序,可以连接到远程数据库并运行多个查询 我正在使用64位F#构建应用程序。我对这条路充满信心 C:\Program Files (x86)\Microsoft SDKs\F#\4.0\Framework\v4.0\fsc.exe 在构建过程中用作F#框架路径。此外,上面的文件路径位于my path环境变量中 每个查询的结构如下: query{expression} |> Seq.toArray |> Array.map (fun q -> {a = q.
C:\Program Files (x86)\Microsoft SDKs\F#\4.0\Framework\v4.0\fsc.exe
在构建过程中用作F#框架路径。此外,上面的文件路径位于my path环境变量中
每个查询的结构如下:
query{expression}
|> Seq.toArray
|> Array.map (fun q -> {a = q.a;
b = q.b;
etc...}
|> writeToJson ("filePath")
当这些查询结果在应用程序的下游使用时,我写入一个JSON
文件
我在查询中使用了Array
s,正如我所包含的那样
<runtime>
<gcAllowVeryLargeObjects enabled="true" />
</runtime>
返回约250万个结果。我将查询结果传送到的sizeof
是8
有人知道如何防止OOM异常发生吗?在
gcAllowVeryLargeObjects
和使用F#64位之间,我本以为可以解决这个问题。基本上,您的应用程序必须进行调试,如果不访问数据库和您的环境,这将很困难
仅仅因为你调用fsc并不意味着它是64位的(尽管通常是)。编译器的各种标志通常通过Visual Studio在.fsproj
文件中设置,但您当然可以手动编辑它
例如,我可以创建一个32位的配置文件:
true
或:
x64
bin\Release\ConsoleApplication8.XML
错误
您可以在FSIAnyCpu.exe中开始测试,它是FSI的64位版本(应该是VSCode上的默认值,可以在VS2015中设置)
use
notlet绑定,这样它将被释放,GC将清理。对于某些数据库,您可以禁用对象跟踪,因为您正在从数据库中读取数据,所以这应该无关紧要Seq
open System
[<EntryPoint>]
let main argv =
let x = Int32.MaxValue /2
printfn "%A" x
let big = Array.init x (fun _ -> "aa")
Console.ReadLine() |> ignore
printfn "%A" big.Length
0
开放系统
[]
让主argv=
设x=Int32.MaxValue/2
printfn“%A”x
让big=Array.init x(fun->“aa”)
Console.ReadLine()|>忽略
printfn“%A”大。长度
0
我会尽量避免使用数组。它应该会有所帮助,因为seq是懒散的,将所有内容都保留为seq
并没有改变查询或OOM异常的行为。顺便说一句,我不确定64位可以寻址多少空间,但这是TB范围。若您的进程是32位的,但在3GB左右可能会遇到麻烦。可能是内存泄漏?对象的大小也不能测量对象占用的实际内存。这将是8字节x2.5M=约20MB,实际上是填充int或字符串的2.5M元素数组的大小。从外观上看,您返回的任何内容都要大得多。哦,因此,尽管大小有限,但我还是先从最简单的解决方案开始:我将writeToJson
函数改为,而不是一次性将整件事写入流。虽然运行所有查询的过程需要>1小时,但我同意这一点。这是最多每月运行一次的功能。
open System
[<EntryPoint>]
let main argv =
let x = Int32.MaxValue /2
printfn "%A" x
let big = Array.init x (fun _ -> "aa")
Console.ReadLine() |> ignore
printfn "%A" big.Length
0