31

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

这适用于.net吗? 你能设置堆大小限制吗?CLR 是否会不断增长其堆,直到达到机器的物理极限?或者,由于某种微妙的原因,我的 Java 闪烁器阻止我看到,这在 .net 中不是问题吗?

4

4 回答 4

27

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

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

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

于 2008-11-19T09:57:03.860 回答
17

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

编辑:似乎还有一点,虽然不是很大。Rick Minerich 关于 GC 设置的博客文章后续文章似乎比我更了解这件事。它们可能是进一步调查的一个很好的起点——但它们主要是标志,而不是 JVM 中可用的内存限制。

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

于 2008-11-19T09:49:40.113 回答
11

您可能想查看System.Runtime.MemoryFailPoint

于 2009-03-18T17:01:01.577 回答
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()/etc 的自定义例程,因此可以为客户端应用程序提供这种类型的控制。这意味着独立的 .Net 应用程序不走运,除非您想用 C++ 编写自定义内存管理器并为 .Net 创建接口

于 2009-08-05T15:31:42.677 回答