我可以(我是否想要)设置 .net 中的最大堆大小?

问题描述 投票:0回答:4

来自 java 背景,我习惯的一件事是告诉 JVM 最大堆大小应该是多少。如果正在运行的程序试图吞咽超过允许的资源,并且垃圾收集器无法释放更多资源,则会抛出 OutOfMemoryError ,一切都会崩溃。所以设置最大堆大小在Java中很重要。

这适用于.net吗?您可以设置堆大小限制吗? CLR 是否会不断增加其堆,直到达到机器的物理极限?或者,由于某些微妙的原因,我的 Java 眼罩阻止我看到,这不是 .net 中的问题吗?

.net performance garbage-collection heap-memory
4个回答
29
投票

除非您自己在进程中托管 CLR,否则无法在 .Net 中设置最大堆大小。

编辑: 要控制 CLR 的内存分配(包括最大堆大小),您需要使用托管 api 来托管 clr,并特别使用“内存管理器接口”,可以在此处找到一些入门信息 MSDN 杂志,CLR Inside Out 专栏: CLR 托管 API

编辑:回答你的问题,为什么你想要控制内存分配或特别是最大堆大小,你通常不想这样做,但是如果你正在编写一个像 SQL Server 或 IIS 或某些应用程序实时应用程序那么你就有充分的理由控制内存,特别是避免分页,否则 CLR 本身和操作系统已经为你做了很好的工作,剩下的就是确保你的应用程序使用使事情顺利进行的最低资源。


18
投票

不,它不适用于.NET。堆确实会不断增长,直到无法再增长为止。 (显然,这是“在尝试通过 GC 恢复内存后,增加堆”。)基本上,.NET GC 中的可用调整并不像 Java 中那么多。你可以选择服务器 GC 或客户端 GC,我认为有一个选项可以打开/关闭并发 GC(我很快就会找到链接),但基本上就是这样。

编辑:似乎还有更多内容,尽管数量不是很多。 Rick Minerich 关于 GC 设置的博客文章后续文章 似乎比我更了解此事。它们可能是任何进一步调查的良好起点 - 但它们主要是标志,而不是 JVM 中可用的内存限制。

编辑:Pop 的回答提出了一个很好的观点 - 我一直假设一个“正常”CLR 托管模型(即不在您的控制之下)。如果您想自己努力托管它,您可能会获得更多的控制权 - 但代价是托管它的额外工作。我不能说我曾经研究过事情的这一面。


11
投票

您可能想查看 System.Runtime.MemoryFailPoint


7
投票

据我发现,没有简单的方法可以使用 CLR 控制 .Net 应用程序的堆大小

上面的链接只回答了问题的一半。当我研究同样的问题时,答案是“堆增长以使用所有可用内存”,好像这是您想要控制最大堆大小的唯一原因。

在(通常是 Java)服务器环境中,您不希望行为不良的应用程序占用其他托管应用程序的内存。一个简单的解决方案是限制应用程序可用于其堆的内存量。这是通过 Java 的 -Xmx 参数完成的,因此您可以保证应用程序不会使用超出计划的内容,例如-Xmx256M。由于在初始化期间在堆上分配内存会减慢应用程序的启动速度,因此 Java 使用 -Xms 参数来允许在初始化期间创建大量对象的应用程序以大块堆开始,而不是 JVM 不断调整堆大小。去。

.Net的CLR不具备这个能力。我怀疑这是因为.Net的CLR不是虚拟机。 CLR 恰好是一个 API(相当全面,我可能会补充),它充当本机 .dll 的适配器,在内存管理方面,这相当于一种更像可执行文件的方法。

我问过这个有关 SharePoint 开发的问题,并且确实听说可以通过使用称为 Web 应用程序的 IIS 模块来控制堆大小,您可以通过该模块告诉 IIS 限制给定 Web 应用程序的内存。我想知道这是否是因为 IIS 有自定义例程来替换/覆盖 new()/malloc()/等,从而可以为客户端应用程序提供这种类型的控制。这意味着独立的 .Net 应用程序不走运,除非您想用 C++ 编写自定义内存管理器并为 .Net 创建接口

© www.soinside.com 2019 - 2024. All rights reserved.