F# 交互式内存泄漏

4
如果我打开 FSI 并粘贴以下内容:
[1..10000000];;
[1..10000000];;
[1..10000000];;
[1..10000000];;
[1..10000000];;
[1..10000000];;
[1..10000000];;
[1..10000000];;
[1..10000000];;

我得到:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.

如果我使用let x =前缀,情况也是一样的。似乎顶层引用仍然被保留,无论它们有多不可访问。有没有什么方法可以清理这些内容,而不会失去能够逐步查看数据的便利性?现在,我只能重新启动来清理,但这很不方便。


1
有点迂腐,但那不是内存泄漏,而只是fsi函数的工作方式。 - N_A
根据维基百科的说法,“内存泄漏可能发生在对象存储在内存中但无法被运行代码访问”的情况下。在这种情况下,“它的功能”就是泄漏内存。 - Lamarth
如果您在自己的可执行程序中执行相同的代码而不是在fsi.exe中执行,它将表现出相同的行为。 - Petr
[<EntryPoint>] let main argv = [1..100000000] [1..100000000] [1..100000000] [1..100000000] [1..100000000] [1..100000000] [1..100000000] [1..100000000] [1..100000000]
printfn "%A" argv 0 // 返回一个整数退出码
- Petr
它在注释中格式不正确,但本质上它基本上是相同的代码封装在主函数中。 - Petr
2个回答

3

我认为在FSI中没有一种方法可以清除顶级引用。您可以使用F# Interactive进程的64位模式来增加FSI可以访问的内存量。在VisualStudio中,这是“工具-选项-F#工具->F#交互”设置。


实际上我正在使用fsianycpu.exe,当它消耗了大约20GB的内存时,我不得不重新启动。 - Lamarth
那么像@jyoung建议的那样使用可变变量可能可以解决问题。 - Petr

2

如果你想使用 let x = [1..10000000],那么请使用:

let mutable x = [1..10000000];; 

使用以下方法来重复使用数据内存:

x <- [1..10000000];;  

释放数据内存可以使用以下方法:

x <- [];; 

太好了!那我只需要执行 System.GC.Collect();,所有的问题都会消失!如果我有耐心的话,它很可能会自动消失。 - Lamarth
好的,这比这更复杂。"x <-\n let y = [1..10000000]\n 0;;"泄漏了,但是"x <-\n let y = [1..10000000]\n List.head y;;"不会泄漏(从"let mutable x = 0"开始)。 - Lamarth

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