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

时间:2008-11-19 09:32:34

标签: .net garbage-collection heap performance

来自java背景,我习惯的一件事就是告诉JVM最大堆大小应该是多少。如果正在运行的程序试图吞下超过允许的数量,并且垃圾收集器无法释放任何更多的资源,那么抛出OutOfMemoryError就会发生爆炸。因此,在Java中设置最大堆大小非常重要。

这适用于.net吗?您可以设置堆大小限制吗? CLR是否只是在它达到机器的物理极限之前不断增长?或者,因为我的Java眼罩阻止我看到它的一些微妙原因,它不是.net中的问题吗?

4 个答案:

答案 0 :(得分:22)

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

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

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

答案 1 :(得分:14)

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

编辑:似乎还有一点,虽然不是很多。 Rick Minerich's blog entry on GC settingsthe subsequent one似乎比我对这个问题了解得多。它们可能是进一步调查的良好起点 - 但它们主要是标志而不是JVM中可用的内存限制。

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

答案 2 :(得分:7)

您可能需要查看System.Runtime.MemoryFailPoint

答案 3 :(得分:5)

据我所知,使用CLR的{。}应用程序的control the size of the heap没有简单的方法。

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

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

.Net的CLR没有这种能力。我怀疑是因为.Net的CLR不是虚拟机。 CLR恰好是一个API(非常全面,我可能会添加),它作为本机.dll的适配器,等同于在内存管理方面更像是可执行文件的方法。

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