问题简介
Out of memory异常是如何产生的
总的来说OutOfMemoryException会在两种情况下发生,
-
进程虚拟内存空间耗尽
-
系统物理内存耗尽
第二种情况我们可以参照系统进程管理器中性能选项卡,如果其中committed数值接近了limit,那说明第二种情况发生了。
不过大多数时候OutOfMemoryException发生是因为第一种原因,接下来我们将重点研究虚拟地址空间耗尽的问题。
无论机器插了多少内存条,32位操作系统可以寻址4GB的地址空间,如果系统没有打开3GB开关的话,其中2GB分配给操作系统内核,另外2GB分配给用户程序。内核的2GB空间被所有的进程,操作系统所共享。但用户模式的那2GB空间为每个进程独享。
我们来简单描述一下CLR内存分配的方式,当应用程序需要分配内存空间的时候,CLR会分配一段连续空间64MB给应用程序使用,如果应用程序需要分配的内存大于85000byte,那么这部分内存会在大对象堆中分配,如果大对象堆中没有这么大的连续内存空间,则为大对象堆分配新的一段16MB。如果一直这样分配下去的话,总会达到一个上限无法满足连续空间的分配请求,因为我们只有2GB的用户模式内存空间。这样outof memory异常就会发生了。当然我们没有讨论垃圾回收器会不停的回收内存,整理压缩空间。
主要两大原因会使进程虚拟内存耗尽,
- 程序分配的速度大于内存回收速度
- 虚拟内存地址空间太多碎片,减少了连续空间分配的可能性
通常情况下,当32位应用程序虚拟内存使用了800M以上的时候,发生out of memory的几率会大大增加,因为内存碎片难以避免,