通过代码实现 OutOfMemory

Intro

来尝试写一个发生 OutOfMemoryException 的代码吧,开启煞笔代码第三篇 —— OutofMemory

OutOfMemory

OutOfMemory 顾名思义就是内存不足,在 .NET 中当内存不足的时候就会抛出 OutOfMemoryException 的异常。

想要触发 OutOfMemoryException 就要满足内存不足的条件,在 .NET Framework 中可能就只能一直分配内存直到内存不足,再没有足够的内存可以分配了,在 .NET Core 3.x 版本以后,微软引入了一些 GC 的配置,我们可以通过这些配置来指定最大的 GC 内存,这样我们就可以实现触发 OutOfMemoryException 而不影响其他应用程序正常运行的目标了。在 .NET 5 中我们又可以更进一步更精细的控制 GC 使用的内存了,在 .NET 5 中我们可以针对每个堆(SOH/LOH/POH)来设置内存限制。

GC 堆内存限制配置

我们测试的示例使用限制 GC 堆大小 (Heap Limit) 的方式来限制应用程序的内存占用以免影响到别的应用程序正常运行(该配置只针对 64 位电脑有效,现在的电脑应该大多都是64位吧)。

配置的方式有两种,一种是通过环境变量来配置,一种是通过 runtime.config.json 来配置

通过环境变量配置 COMPlus_GCHeapHardLimit 为要配置的内存大小,需要注意的是通过环境变量配置的时候指定的值需要是十六进制的值,通过 runtimeconfig.json 配置的时候是直接用十进制的数值

因为我们只是想简单的测试一下,不能影响别的应用程序,而且不能在代码里配置当前进程的环境变量,因为进程启动的时候 GC 的配置就已经加载好了,在代码里配置当前进程的环境变量来改变 GC 配置是不会生效的,所以我们选择配置 runtimeconfig.json 来测试,在项目的 bin 目录下可以找到 runtimeconfig.json 文件,我们修改这一个文件即可(使用 runtimeconfig.json 的时候需要注意先生成一下,然后再更新 runtimeconfig.json 文件)

测试配置如下,配置的 GC 堆的最大值是 1M(配置的不能太小,太小的话 CoreCLR 可能都会启动失败从而导致程序无法正常运行):

{"runtimeOptions": {"tfm": "netcoreapp3.1","framework": {"name": "Microsoft.NETCore.App","version": "3.1.0"},"configProperties": {"System.GC.HeapHardLimit": 1048576}}
}

测试代码

测试代码如下:

Console.ReadLine();
var bytes = GC.GetTotalAllocatedBytes();
Console.WriteLine($"AllocatedBytes: { bytes } bytes");
var list = new List<byte[]>();
try
{while (true){list.Add(new byte[85000]);}
}
catch (OutOfMemoryException)
{Console.WriteLine(nameof(OutOfMemoryException));Console.WriteLine(list.Count);bytes = GC.GetTotalAllocatedBytes();Console.WriteLine($"AllocatedBytes: { bytes } bytes");
}
Console.ReadLine();

测试输出如下:

上面的测试代码使用的 byte 数组的长度是 85000 的原因是,当要分配的对象大于等于 85k(85000)时会直接分配到大对象堆中,正好可以测试一下。

我们使用微软的 dotnet dump 诊断工具来测试一下

第一次 dump 是在 list 对象创建之前进行的,第二次 dump 是发生 OutOfMemory 之后的

从上面的 dump 结果可以看的出来,byte 数组的对象确实是分配在大对象堆(LOH)上的,几乎所有的内存分配都在大对象堆中,有一些小对象从0 代升到了 1代。

More

上面的测试代码使用的 byte 数组的长度是 85000 ,你测试的时候也可以使用更大的值,或者直接使用 int.MaxValue

在前面的 StackOverflow 文章中,有网友评论说,他们之前遇到的一个 StackOverflow 示例常常伴随着 OutOfMemory ,递归和这种方式有点类似,都是要一直创建新的对象,分配新的内存。

除此之外,还有哪些更简单的方式吗?欢迎补充

References

  • https://docs.microsoft.com/en-us/dotnet/core/run-time-config/garbage-collector#heap-limit

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/StupidSamples/FullMemorySample.cs

实现 OutOfMemory​相关推荐

  1. 一个GDIPlus的Bug -- OutofMemory异常

    今天发现 framework2.0中的一个GDIPlus的Bug: 在Form的OnPaint事件里面写如下代码: private void Form1_Paint(object sender, Pa ...

  2. 记一次OutOfMemory定位过程

    背景 最近有个项目部署到了AWS,部署方案是ECS+Docker+Java Launch type CPU Units Memory FARGATE 1024 4G 运行后发现程序表现不符合预期--每 ...

  3. zz 标 题: 求weka JVM outofMemory问题的解决方案【已解决】

    发信人: finallyliuyu (领头驴), 信区: NLP 标  题: 求weka JVM outofMemory问题的解决方案 发信站: 水木社区 (Sun Feb 20 10:36:12 2 ...

  4. java io内存泄露_java内存泄露和OutOfMemory

    1.内存泄露: Java的内存泄漏是指某些对象不再被应用程序使用,而垃圾收集器(Garbage Collector)却没能识别它们是"不再使用的",所以没有对这些对象进行回收,或者 ...

  5. JVM调优:Tomcat Context reloadabled与OutOfMemory(PermSpace)

    转载自:http://ayufox.iteye.com/blog/646125 我们知道,Sun JVM分代垃圾回收器把堆空间分成3块: Young Gen:年轻代,包括1个Eden区和2个Suviv ...

  6. Android Bitmap OutOfMemory 解决的方法

    在Android应用里,最耗费内存的就是图片资源.并且在Android系统中.读取位图Bitmap时,分给虚拟机中的图片的堆栈大小仅仅有8M.假设超出了.就会出现OutOfMemory异常 E/And ...

  7. Android Bitmap OutOfMemory 解决办法

    Android Bitmap OutOfMemory 解决办法 置顶 2014年07月01日 14:41:22 阅读数:3072 标签: OutOfMemoryBitmapandroid图片优化更多 ...

  8. outofmemory异常如何解决?

    一年多来打交道最多的就是WinForm,界面设计确实比MFC容易多了,但是问题出的也更隐晦,要想完全解决还是离不开框架底层的知识. 现在又遇到了一个麻烦的问题:切换界面时,有时GroupBox(里面嵌 ...

  9. tomcat 系统服务 outofmemory

    TOMCAT内存溢出outofmemory的问题: http://hi.baidu.com/mefeng47/item/3b247af74ce4e24e922af2e5 注:双击tomcat6w.ex ...

最新文章

  1. 我的微型计算机,我的OC(超频)18年追忆!
  2. 黑马程序员pink老师前端入门教程,零基础必看的JavaScript基础语法视频教程
  3. Luogu P4708 画画 (Burnside引理、组合计数)
  4. 学习 WCF (5)--学习Binding的使用
  5. 自定义控件的构建(12)
  6. jboss 程序位置_介绍JBoss BPM Suite安装程序
  7. wex5部署教程到数据库
  8. webservice使用EF生成的model序列化问题
  9. 解决Eclipse无法添加Tomcat服务器的问题
  10. 2012.12.26 晚 小雨
  11. 关于Adaper的相关用法
  12. 傅里叶变换与拉普拉斯变换
  13. HTML---鼠标悬停导航栏变颜色
  14. ​RS232串口线常见接法与引脚定义
  15. linux wps 微软雅黑字体,微软雅黑字体下载,微软雅黑字体下载应用到wps
  16. 4.蒙特卡洛(Monte-Carlo, MC)+时序差分(Temporal Difference, TD)
  17. Mac 运行windows软件
  18. 【教程】小米手机Android 7.0+抓取HTTPS请求安装Charles证书主要流程
  19. 笔记本键盘进水几个按键失灵 还能修好么_苹果首台笔记本Mac Portable全拆卸,蒂姆·库克签名,无螺丝设计,机械键盘...
  20. Chrome调试以及选择清除缓存刷新

热门文章

  1. 驱动之LCD的介绍与应用20170209
  2. sql学习笔记---公用表达式(CTE)
  3. Codeforces Round #260 (Div. 2)
  4. 我到底要选择一种什么样的生活方式,度过这一辈子呢:人生自由与职业发展方向(下)...
  5. Ubuntu 下配置 NFS
  6. 清华经管计算机金融专业,非量化背景拿下MIT MFin的清华经管学姐,详解MIT金融项目优劣和职业方向...
  7. 使用SMART监控Ubuntu
  8. 翻译:用户变量(User-Defined Variable)(已提交到MariaDB官方手册)
  9. 前端实现连连看小游戏(1)
  10. php的几种运行模式CLI、CGI、FastCGI、mod_php