可变应用程序上下文



我正在构建一个REST后端,它需要大量的值来计算答案。此集合在启动时下载,然后按需下载,但需要每天更新几次。我不知道如何应对这种可变状态。我已经在 main 函数中尝试了 ref 和可变变量,但旧集合从未发布,内存使用量不受控制地增长。

处理这种可变状态的正确方法是什么?

编辑

在准备我正在做的事情的样本时,我发现了第一个错误。我在做:

let sqlfeed() = use cmd = new SqlFeedType(connectionString) Some (cmd.Execute() |> Seq.toList)

现在我正在做这样的事情:

let sqlfeed() = Some (using (new SqlFeedType(connectionString)) (fun cmd -> cmd.Execute() |> Seq.toList))

然后

[<EntryPoint>]
let main argv =
let optionSqlFeed = ref None
let app =
choose [
Filters.path "/sqlfeed" >=> warbler (fun ctx -> 
match !optionSqlFeed with
| None ->
optionSqlFeed := sqlfeed()
| Some a ->
optionSqlFeed := None
Successful.OK "done" ) 
]
startWebServer defaultConfig app

以前,当我调用sqlfeed并下载数据时,我看到内存增加了。在交替分配给 None 的连续调用中,不会释放内存,并且总使用量会攀升。 现在,当我调用 sqlfeed 并将 None 分配给可变变量时,内存仍然没有释放,但在下次调用 sqlfeed 时,内存被释放。

为什么在分配 None 时不会释放内存,但在再次调用 sqlfeed 时会释放内存?

GC 在运行时不是确定性的。当您再次调用sqlfeed()时,它会对应用程序施加内存压力,我敢打赌这有时会触发垃圾收集,而将变量设置为无值不会占用额外的内存。

存在的物理内存量会影响垃圾回收的发生时间,如果可能,它是延迟的 - CLR 垃圾回收器频率和系统内存可用。

当您将变量设置为None时,您可以自行触发 GC,但这可能不是一个好主意 - 何时可以接受调用 GC。收集?

来自:了解 .NET 中的垃圾回收

气相色谱。Collect() 将只运行垃圾回收的跟踪部分 并将项目添加到终结器队列,但不调用终结器。 类型,由另一个线程处理。

如果您希望根据需要释放当前值而不是无限期保留,请使用WeakReference弱引用是否是一个很好的缓存?

相关内容

最新更新