对 .NET程序2G虚拟地址紧张崩溃 的最后一次反思

一:背景

1. 讲故事

最近接连遇到了几起 2G 虚拟地址紧张 导致的程序崩溃,基本上 90% 都集中在医疗行业,真的很无语,他们用的都是一些上古的 XP,Windows7 x86,我也知道技术人很难也基本无法推动硬件系统和设备的升级,这里蕴含了巨大的人情世故。

写这一篇的目的是想系统化的整理一下如何配置 3G 开关让程序吃到更多的内存,让程序崩溃的不那么频繁一些,以及如何验证是否成功开启!

二:32位操作系统

1. 测试代码

首先大家要有一个理念:就是 32bit系统上跑的程序,默认只能吃到 2G 内存,因为这涉及到公平,用户态吃2G,内核态吃2G,为了方便演示,向一个 List 塞入 5000w 的 string,大概占用 2G 内存,然后把程序跑在 Windows7 32bit 操作系统上。

static void Main(string[] args){var list = new List<string>();for (int i = 0; i < 50000000; i++){list.Add(i.ToString());if (i % 10000 == 0) { Console.WriteLine($"i={i}"); }}Console.WriteLine("ok");Console.ReadLine();}

从图中可以清楚的看到当内存到了631M 的时候就扛不住了,可能有些朋友好奇,为什么才这么点就不行了,这是因为 List 的底层是 2倍 扩容,所以内存大概会涨到 0.63G + 1.2G = 1.83G

有些朋友可能会问,这不是还没到2G吗?一般来说内存到了 1.2G+ 的时候崩溃风险就会剧增,这个要谨记!

2. 如何解决

刚才也说了,医疗行业现状如此,只能通过人情世故去推动,那这 2G 数据真的无处安放吗? 这时候就只能启动 3G 开关,那如何启动呢?

  1. 开启程序级的 Large Address Aware

这个 Large Address Aware 字段俗称大地址,途径就是在 PE 头里打开一个开关,让Windows加载器决定是否给程序打开 3G 的绿色通道。

当然看 PE头 的工具有很多,对于.NET程序个人感觉最好的就是用 DnSpy,它把 File Header 中的 Characteristics 字段具化了,我们选中 Large Address Aware 复选框然后保存,截图如下:

  1. 开启机器级别 3G 开关

在32bit操作系统上让用户态程序吃到 3G 内存这对操作系统来说是非常谨慎的,毕竟这对内核态是非常不公平的,言外之意就是让出自己的 1G 给用户态,这骚操作可能就会把自己坑惨,谨慎起见需要人工开启机器级别的 3G 开关,命令如下:


bcdedit /set IncreaseUserVa 3072

做了这两步之后,继续让程序跑起来,截图如下:

从图中可以清晰的看到,终于有出息了。

更多操作系统配置,可参考这篇文章:https://www.autodesk.com.cn/support/technical/article/caas/sfdcarticles/sfdcarticles/CHS/How-to-enable-a-3GB-switch-on-Windows-Vista-Windows-7-or-Windows-XP-s.html?v=2018

3. 如何验证是否开启了 3G

这确实是一个好问题,最简单的方式就是用!address 观察下地址空间。


0:000> !addressBaseAddr EndAddr+1 RgnSize     Type       State                 Protect             Usage
-----------------------------------------------------------------------------------------------
...
+ bffde000 bffdf000     1000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     TEB        [~0; aa4.fb8]
+ bffdf000 bffe0000     1000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     PEB        [aa4]
+ bffe0000 bfff0000    10000 MEM_PRIVATE MEM_RESERVE PAGE_NOACCESS                      <unknown>  0:000> ? bfff0000/0x100000
Evaluate expression: 3071 = 00000bff

上面卦中的 bfff0000 转换过来就是 3G,如果你看到的是这个值,那就恭喜你啦!

如果有朋友想问如何验证 dump程序是否开启了大地址,这个可以用windbg提供的 !dh 命令。


0:000> lm
start    end        module name
001e0000 001e8000   ConsoleApp4 C (pdb symbols)          D:\code\MyApplication\ConsoleApp4\obj\x86\Debug\ConsoleApp4.pdb
66dd0000 678c8000   mscorlib_ni   (deferred)             
678d0000 67e61000   mscorwks   (deferred)             
6c7a0000 6c83b000   msvcr80    (deferred)  
...
0:000> !dh ConsoleApp4File Type: EXECUTABLE IMAGE
FILE HEADER VALUES14C machine (i386)3 number of sections
EDB20AC7 time date stamp0 file pointer to symbol table0 number of symbolsE0 size of optional header122 characteristicsExecutableApp can handle >2gb addresses32 bit word machine

如果看到上面卦中的 App can handle >2gb addresses 字样就表示你开启成功啦!

三:64位操作系统

1. 如何吃更多内存

在 x64系统上就方便多了, 只需要做第一步开启 Large Address Aware 即可,毕竟 x64系统 的虚拟地址空间不要太充足,在 48根地址总线上就是2的48次方,所以开启大地址后,会给 x32 程序4G的寻址空间,即 2 的 32 次方。

接下来直接把刚才的 ConsoleApp4.exe 程序从 Windows7 x86 搬迁到 Windows 10 x64 系统上,然后用 windbg 附加运行, 跑完后使用 !address 查看。


0:007> !address BaseAddr EndAddr+1 RgnSize     Type       State                 Protect             Usage
-----------------------------------------------------------------------------------------------
+        0   c60000   c60000             MEM_FREE    PAGE_NOACCESS                      Free     
...
+ ff671000 ff680000     f000             MEM_FREE    PAGE_NOACCESS                      Free       
+ ff680000 ff6b3000    33000 MEM_MAPPED  MEM_COMMIT  PAGE_READONLY                      Other      [NLS Tables]
+ ff6b3000 ffff0000   93d000             MEM_FREE    PAGE_NOACCESS                      Free       0:007> ? ffff0000 /0x100000
Evaluate expression: 4095 = 00000fff

如果在你的卦中也看到了上面的 ffff0000 ,那就恭喜你,你程序的内存寻址空间扩展到了 4G 。

三:总结

本篇说了这么多,其实都是一些不得已而为之的事情,很心酸,这世上很多东西不是靠技术就能解决的,更需要靠人情事故!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/167055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抖音获客策略:让你的品牌在短视频平台一鸣惊人!

一、背景介绍 随着移动互联网的快速发展&#xff0c;抖音作为一款流行的短视频平台&#xff0c;已经成为越来越多企业的获客渠道。抖音用户规模庞大&#xff0c;日活用户数量不断增长&#xff0c;为企业提供了广阔的市场空间。本文将介绍抖音获客策略&#xff0c;帮助企业更好…

UNETR++:深入研究高效和准确的3D医学图像分割

论文&#xff1a;https://arxiv.org/abs/2212.04497 代码&#xff1a;GitHub - Amshaker/unetr_plus_plus: UNETR: Delving into Efficient and Accurate 3D Medical Image Segmentation 机构&#xff1a;Mohamed Bin Zayed University of Artificial Intelligence1, Univers…

哦?是吗|兜兜转转,最后还是选择了盖雅排班系统

在之前发布的和「人效案例集」中&#xff0c;我们为大家呈现了很多关于人效提升的理论方法&#xff0c;以及各家企业的人效提升提升实践。 回过头来&#xff0c;我们发现&#xff1a;排班管理渗透于人效九宫格之中&#xff0c;也因此成为很多企业人效提升的一个重要中介&#x…

深度学习八股文:混合精度训练过程出nan怎么办

其实如果是FP32的训练&#xff0c;基本的调试方法还是差不多&#xff0c;这里就讲一下混合精度训练过程中的nan。 混合精度训练使用较低的数值精度&#xff08;通常是半精度浮点数&#xff0c;例如FP16&#xff09;来加速模型训练&#xff0c;但在一些情况下&#xff0c;可能会…

盘点43个Python登录第三方源码Python爱好者不容错过

盘点43个Python登录第三方源码Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 项目名称 bnuz中国电信校园网模拟登录&#xff0c;python selenium BNUZ教务系统认证爬虫Python语言实现&#xff0c;你可以用…

NX二次开发UF_CSYS_create_temp_csys 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_create_temp_csys Defined in: uf_csys.h int UF_CSYS_create_temp_csys(const double csys_origin [ 3 ] , tag_t matrix_id, tag_t * csys_id ) overview 概述 Creates …

win10 tensorrt源码编译onnx

直接利用官方源码&#xff0c;如下图&#xff0c;trtexec源码在TensorRT安装目录下&#xff0c;双击trtexec.sln文件&#xff0c;使用vs2019打开源码工程。 如下图&#xff0c;以yolov8为例子&#xff0c;编译成功项目之后&#xff0c;设置命令行参数&#xff1a; --onnxd:/yo…

便携式工业RFID读写器怎么选?

便携式工业RFID读写器在物流、零售、制造等行业都有着极为广泛的应用。企业利用RFID手持终端设备&#xff0c;可以将采集到的物品信息自动传输到中央信息系统&#xff0c;实现数据的实时交换和共享。目前市面上RFID手持终端品牌、型号众多&#xff0c;ANDEAWELL作为国内物联网产…

案例精选|聚铭网络流量智能分析审计系统加强南京市溧水区人社局信息安全防护能力

一字排开的社保综合服务窗口、实时滚动的数“智”人社大屏、便捷快速的社保卡自助服务机……每位到溧水市民中心人社大厅进行业务办理的市民对高效的社保服务经办效率赞叹不已。 党的二十大报告提出&#xff0c;健全覆盖全民、统筹城乡、公平统一、安全规范、可持续的多层次社…

浅谈Linux bash脚本----截取字符串

# 用于删除左起第一个匹配内容&#xff0c;即截取右侧内容 ## 用于删除右起第一个匹配内容&#xff0c;即截取右侧内容 % 用于删除右起第一个匹配内容&#xff0c;即截取左侧内容 %% 用于删除左起第一个匹配内容&#xff0c;即截取左侧内容 举例 file/dir1/dir2/dir3/…

GPT2-chitchat项目运行

git clone https://github.com/yangjianxin1/GPT2-chitchat.git把项目拉下来 下载模型文件&#xff1a; 从[模型分享]中下载模型文件&#xff0c;例如 model_epoch40_50w。 将模型文件放到正确的位置&#xff1a; 将下载的模型文件夹 model_epoch40_50w 放到项目的 model 目录…

深入理解数据结构:队列的实现及其应用场景

文章目录 &#x1f342;前言&#x1f342;队列的基本概念和特性&#x1f342;队列的实现方式️&#x1f331;顺序队列️&#x1f331;链式队列 &#x1f342;队列的基本操作及示例代码️&#x1f951;创建队列️&#x1f951;判空操作️&#x1f951;入队操作️&#x1f951;出…

GEE:APP中的遥感图像下载接口设计

作者:CSDN @ _养乐多_ 本文将详细介绍如何通过Google Earth Engine(GEE)的用户界面(ui)模块创建一个下载按钮,以触发遥感图像下载的操作。通过按钮的点击事件,我们生成了包含特定参数的图像下载链接,实现了一键式遥感图像下载功能,使整个过程更加智能和直观。 此外,…

java操作富文本插入到word模板

最近项目有个需求&#xff0c;大致流程是前端保存富文本&#xff08;html的代码&#xff09;到数据库&#xff0c;后台需要将富文本代码转成带格式的文字&#xff0c;插入到word模板里&#xff0c;然后将word转成pdf&#xff0c;再由前端调用接口下载pdf文件&#xff01; 1、思…

代码随想录算法训练营第30天|回溯总结 332. 重新安排行程

回溯是递归的副产品&#xff0c;只要有递归就会有回溯&#xff0c;所以回溯法也经常和二叉树遍历&#xff0c;深度优先搜索混在一起&#xff0c;因为这两种方式都是用了递归。 回溯法就是暴力搜索&#xff0c;并不是什么高效的算法&#xff0c;最多再剪枝一下。 回溯算法能解…

Linux安装Tesseract-OCR(操作系统CentOS)

Linux安装Tesseract-OCR 第一步&#xff0c;安装依赖第二步&#xff0c;下载安装包第三步&#xff0c;安装leptonica库第四步&#xff0c;安装tesseract第五步&#xff0c;添加语言包第六步&#xff0c;测试 第一步&#xff0c;安装依赖 sudo yum install libpng-devel rpm -q…

从零学算法400

400.给你一个整数 n &#xff0c;请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …] 中找出并返回第 n 位上的数字。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;n 11 输出&#xff1a;0 解释&#xff1a;第…

ubuntu22.04 arrch64版在线安装mysql8

脚本 # todo参考链接 Ubuntu服务器配置mysql8_ubuntu安装mysql8-CSDN博客

乐得瑞LDR6020 VR串流线方案:实现同时充电传输视频信号

VR&#xff08;Virtual Reality&#xff09;&#xff0c;俗称虚拟现实技术&#xff0c;是一项具有巨大潜力的技术创新&#xff0c;正在以惊人的速度改变我们的生活方式和体验&#xff0c;利用专门设计的设备&#xff0c;如头戴式显示器&#xff08;VR头盔&#xff09;、手柄、定…

三菱PLC定时中断应用编程(计数器+比较器)

三菱PLC如何开启定时中断可以查看下面文章链接: PLC定时中断程序应用注意事项(西门子三菱信捷)_plc设置断点之后会怎样_RXXW_Dor的博客-CSDN博客文章浏览阅读2.5k次,点赞5次,收藏6次。首先我们了解下什么是中断。中断(打断的意思),在PLC执行当前程序时,由于系统出现了…