C#/.Net框架中的堆大小-它能增长吗?如何增长?
我在我的一本大学书中遇到了一件令人困惑的事情: 这里指出“堆不是静态的,可以通过从操作系统请求更多内存来根据需要增长” 所以我感到困惑的是:假设我运行我的应用程序,并且在堆上分配对象。在某个时刻,应用程序内存不足:现在会发生什么 据我所知,Gc(垃圾收集器)启动并开始它的标记和扫描操作。我想知道堆是否有可能从操作系统请求更多内存,而不是由CLR调用GcC#/.Net框架中的堆大小-它能增长吗?如何增长?,c#,.net,memory-management,garbage-collection,heap,C#,.net,Memory Management,Garbage Collection,Heap,我在我的一本大学书中遇到了一件令人困惑的事情: 这里指出“堆不是静态的,可以通过从操作系统请求更多内存来根据需要增长” 所以我感到困惑的是:假设我运行我的应用程序,并且在堆上分配对象。在某个时刻,应用程序内存不足:现在会发生什么 据我所知,Gc(垃圾收集器)启动并开始它的标记和扫描操作。我想知道堆是否有可能从操作系统请求更多内存,而不是由CLR调用Gc 我读到C++语言有一种方法可以实现,但是在C .net框架4.5?< /p> 中,堆是动态的,在这个意义上,当你添加到堆时,它会增长。它创建指向
<>我读到C++语言有一种方法可以实现,但是在C .net框架4.5?< /p> 中,堆是动态的,在这个意义上,当你添加到堆时,它会增长。它创建指向内存中其他位置的指针。应用程序在内存耗尽之前所能占用的内存大小总是有限制的。当达到限制时,通常会出现“内存不足”异常
阅读wiki可能会有所帮助:
Net中的堆是内存的一部分,在实际应用中,32位进程的最大容量可达1.5GB左右,64位进程的最大容量不受限制(同样,在实际应用中也是如此),并且它确实会根据需要从操作系统请求内存。但是,由于过度碎片化和使用大型分配,它可能会耗尽内存—GC不会压缩大型对象堆
当您在C++中完成时,您完全控制了如何在内存中分配内存分配策略,在.NET中为您完成了,并且您对如何完成该操作几乎没有发言权,尽管大部分情况下它做的非常好。
堆因为您的应用程序分配和保持对象而增长。每当应用程序需要存储指向应用程序当前正在使用的对象的指针时,堆都会请求内存
每当堆用完时,就会收到错误提示,提示堆内存不可用或类似的情况。为了避免这种GC,如果您实现自己的CLR主机,您可以控制这种行为 您可以做一些事情来限制内存使用。请参阅此问题以获取一些输入: 要了解有关堆(ing)和堆栈(ing)的更多信息,请参阅以下链接:认识到这一点很重要。这意味着您的虚拟内存不足。在32位应用程序中,该应用程序虚拟地址空间中的项有2^32个可能的地址 操作系统负责将虚拟地址空间的各个部分映射到实际的物理存储介质,无论是RAM、硬盘驱动器还是任何其他存储设备。由于大多数应用程序都没有使用其虚拟地址空间的绝大多数,因此大部分虚拟地址空间都映射为空,并且在开始使用之前不会与任何内容对应 虽然一个程序可能会改变,但什么虚拟内存块与实际的物理内存块相对应(一个程序一次使用超过2^32个字的内存所需的)这样做并不常见,通常仅由视频处理应用程序等确实需要一次性存储大量内存的程序完成。这个过程也是手动的。如果不手动交换每个虚拟内存块映射到的内容,则可能会耗尽虚拟内存,即使您仍然拥有能够存储更多信息的存储设备。这是一个内存不足的错误 在C#应用程序中,堆几乎是堆栈未占用的全部虚拟地址空间、静态字段的存储以及任何其他开销,如程序实际代码的内存。从应用程序的角度来看,堆从一开始就是最大的。操作系统已经抽象出一个事实,即C#runtime所认为的“它的内存”实际上并不映射到任何地方,因为它没有被使用;当您开始使用堆的更多部分时,越来越多的堆实际上被映射到某种形式的物理存储
如果您有一个64位的应用程序,您基本上可以在此回答中将
32
的所有实例替换为64
。通过将应用程序构建为64位体系结构,您可以分配比~2 GB多得多的内存,这需要您创建一个新的构建配置。使用.NET项目的正常(默认)“任意CPU”构建选项,应用程序将始终在32位模式下运行,即使在64位Windows操作系统上也是如此。因此,在应用程序执行期间,您将无法分配超过1.5到2 GB的RAM内存。要在真正的64位模式下运行.NET应用程序,您需要进入构建配置管理器,为x64体系结构创建一个构建类型,然后使用该构建类型显式地重新编译x64的程序。可以使用以下步骤为.NET解决方案创建x64生成模式选项: