对 .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 开关,那如何启动呢?
- 开启程序级的 Large Address Aware
这个 Large Address Aware 字段俗称大地址,途径就是在 PE 头里打开一个开关,让Windows加载器决定是否给程序打开 3G 的绿色通道。
当然看 PE头 的工具有很多,对于.NET程序个人感觉最好的就是用 DnSpy,它把 File Header 中的 Characteristics 字段具化了,我们选中 Large Address Aware 复选框然后保存,截图如下:

- 开启机器级别 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 。
三:总结
本篇说了这么多,其实都是一些不得已而为之的事情,很心酸,这世上很多东西不是靠技术就能解决的,更需要靠人情事故!
相关文章:
对 .NET程序2G虚拟地址紧张崩溃 的最后一次反思
一:背景 1. 讲故事 最近接连遇到了几起 2G 虚拟地址紧张 导致的程序崩溃,基本上 90% 都集中在医疗行业,真的很无语,他们用的都是一些上古的 XP,Windows7 x86,我也知道技术人很难也基本无法推动硬件系统和…...
HCIA-RS基础-静态路由协议
摘要:静态路由是一种在网络中广泛应用的路由选择方案,它以其简单的配置和低开销而备受青睐。本文将介绍静态路由的配置方法、默认路由的设置、路由的负载分担和备份策略。通过学习本文,希望可以你能够掌握静态路由的基本概念和在华为模拟器中…...
LeetCode(46)汇总区间【区间】【简单】
目录 1.题目2.答案3.提交结果截图 链接: 汇总区间 1.题目 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某…...
数据预处理:随机裁剪放缩
随机裁剪放缩是一种数据增强技术,可以在训练神经网络时增加数据的多样性,提高模型的泛化能力。具体来说,随机裁剪放缩可以通过随机裁剪和缩放原始图片来生成多个不同的训练样本,从而增加数据集的大小和多样性。这种技术在图像分类…...
RabbitMQ 搭建和工作模式
MQ基本概念 1. MQ概述 MQ全称 Message Queue([kjuː])(消息队列),是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。 (队列是一种容器,用于存放数据的都是容器࿰…...
一起学docker系列之七docker容器卷技术
目录 1 为什么使用容器数据卷?2 数据卷的特点和优势3 使用数据卷的方法3.1 创建容器并挂载数据卷3.2 容器间数据卷的共享与继承 4 数据卷的权限设置5 注意事项5.1 解决权限问题5.2 路径自动创建 结语 对于容器化应用程序的数据管理和持久化,Docker 数据卷…...
Loki安装部署
Loki安装部署 1、Loki介绍 Loki 是受 Prometheus 启发由 Grafana Labs 团队开源的水平可扩展,高度可用的多租户日志聚合系统。开发语 言: Google Go。它的设计具有很高的成本效益,并且易于操作。使用标签来作为索引,而不是对全文进行检索&…...
php如何实现文件上传
php实现文件上传需要通过全局变量(数组):$_FILES 结合 move_uploaded_file 函数来实现。 move_uploaded_file函数(只对POST方式生效): 其中move_uploaded_file函数语法:move_uploaded_file(需要…...
实验8配置工具
一、实验目的 1. 掌握UML中建模工具——部署图,用于显示系统中软件和硬件的物理架构。 2. 掌握应用Visio等业界常用的建模工具的基本使用方法和基本绘图操作,选择一种并熟练使用,会使用该工具针对具体问题建立分析模型。 二、实验内容与步骤…...
论文笔记:详解NEUPSL DSI
《Using Domain Knowledge to Guide Dialog Structure Induction via Neural Probabilistic 》 名词解释 Dialog Structure Induction(DSI)是推断给定目标导向对话的潜在对话结构(即一组对话状态及其时间转换)的任务。它是现代对…...
shared_ptr子类指针转换成父类指针
假设有如下应用场景: class Base { public:void addChild(std::shared_ptr<Base>& child){...} }class Derived : public Base {}int main() {Base a;std::shared_ptr<Derived> b std::make_shared<Derived>();a.addChild(b); // Error } 该代码中声…...
五、cookie、session、token、localstroage、sessionStroage区别
一、localStorage 跟 sessionStorage有什么不同???? localStorage 1、生命周期:localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据&am…...
基于SpringBoot的在线视频教育平台的设计与实现
摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于在线视频教育平台当然也不能排除在外,随着网络技术的不断成熟,带动了在线视频教育平台,它彻底改变了过…...
Vue 2.0源码分析-渲染函数render
Vue 的 _render 方法是实例的一个私有方法,它用来把实例渲染成一个虚拟 Node。它的定义在 src/core/instance/render.js 文件中: Vue.prototype._render function (): VNode {const vm: Component thisconst { render, _parentVnode } vm.$options//…...
阿里云国际短信业务网络超时排障指南
选取一台或多台线上的应用服务器或选取相同网络环境下的机器,执行以下操作。 获取公网出口IP。 curl ifconfig.me 测试连通性。 (推荐)执行MTR命令(可能需要sudo权限),检测连通性,执行30秒。 m…...
浅用tensorflow天气预测
1.开发环境 (1)Python3.8 (2)Anaconda3 (3)Tensorflow (4)Numpy (5)Pandas (6)Sklearn 先依次安装好上面的软件和包…...
基于SpringBoot学生读书笔记共享
摘 要 本论文主要论述了如何使用JAVA语言开发一个读书笔记共享平台 ,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述读书笔记共享平台的当前背景以及系统开发的…...
设计模式之装饰模式(2)--有意思的想法
目录 背景概述概念角色 基本代码分析❀❀花样重难点聚合关系认贼作父和认孙做父客户端的优化及好处继承到设计模式的演变过程 总结 背景 这是我第二次写装饰模式,这一次是在上一次的基础上进一步探究装饰模式,这一次有了很多新的感受和想法,也…...
深入了解 Pinia:现代 Vue 应用的状态管理利器
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...
TTS声音合成:paddlespeech、sherpa-onnx、coqui-ai
1、百度TTS文本合成语音 参考: https://aistudio.baidu.com/aistudio/projectdetail/5237474 https://www.jianshu.com/p/a7522ca6dec4 https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/demos/text_to_speech/README_cn.md 1)过程中需要下载的TTS 声学相关模型…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
