当前位置: 首页 > news >正文

对 .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 。

三:总结

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

相关文章:

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

一&#xff1a;背景 1. 讲故事 最近接连遇到了几起 2G 虚拟地址紧张 导致的程序崩溃&#xff0c;基本上 90% 都集中在医疗行业&#xff0c;真的很无语&#xff0c;他们用的都是一些上古的 XP&#xff0c;Windows7 x86&#xff0c;我也知道技术人很难也基本无法推动硬件系统和…...

HCIA-RS基础-静态路由协议

摘要&#xff1a;静态路由是一种在网络中广泛应用的路由选择方案&#xff0c;它以其简单的配置和低开销而备受青睐。本文将介绍静态路由的配置方法、默认路由的设置、路由的负载分担和备份策略。通过学习本文&#xff0c;希望可以你能够掌握静态路由的基本概念和在华为模拟器中…...

LeetCode(46)汇总区间【区间】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 汇总区间 1.题目 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某…...

数据预处理:随机裁剪放缩

随机裁剪放缩是一种数据增强技术&#xff0c;可以在训练神经网络时增加数据的多样性&#xff0c;提高模型的泛化能力。具体来说&#xff0c;随机裁剪放缩可以通过随机裁剪和缩放原始图片来生成多个不同的训练样本&#xff0c;从而增加数据集的大小和多样性。这种技术在图像分类…...

RabbitMQ 搭建和工作模式

MQ基本概念 1. MQ概述 MQ全称 Message Queue&#xff08;[kjuː]&#xff09;&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。 &#xff08;队列是一种容器&#xff0c;用于存放数据的都是容器&#xff0…...

一起学docker系列之七docker容器卷技术

目录 1 为什么使用容器数据卷&#xff1f;2 数据卷的特点和优势3 使用数据卷的方法3.1 创建容器并挂载数据卷3.2 容器间数据卷的共享与继承 4 数据卷的权限设置5 注意事项5.1 解决权限问题5.2 路径自动创建 结语 对于容器化应用程序的数据管理和持久化&#xff0c;Docker 数据卷…...

Loki安装部署

Loki安装部署 1、Loki介绍 Loki 是受 Prometheus 启发由 Grafana Labs 团队开源的水平可扩展&#xff0c;高度可用的多租户日志聚合系统。开发语 言: Google Go。它的设计具有很高的成本效益&#xff0c;并且易于操作。使用标签来作为索引&#xff0c;而不是对全文进行检索&…...

php如何实现文件上传

php实现文件上传需要通过全局变量&#xff08;数组&#xff09;&#xff1a;$_FILES 结合 move_uploaded_file 函数来实现。 move_uploaded_file函数&#xff08;只对POST方式生效&#xff09;&#xff1a; 其中move_uploaded_file函数语法&#xff1a;move_uploaded_file(需要…...

实验8配置工具

一、实验目的 1. 掌握UML中建模工具——部署图&#xff0c;用于显示系统中软件和硬件的物理架构。 2. 掌握应用Visio等业界常用的建模工具的基本使用方法和基本绘图操作&#xff0c;选择一种并熟练使用&#xff0c;会使用该工具针对具体问题建立分析模型。 二、实验内容与步骤…...

论文笔记:详解NEUPSL DSI

《Using Domain Knowledge to Guide Dialog Structure Induction via Neural Probabilistic 》 名词解释 Dialog Structure Induction&#xff08;DSI&#xff09;是推断给定目标导向对话的潜在对话结构&#xff08;即一组对话状态及其时间转换&#xff09;的任务。它是现代对…...

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有什么不同&#xff1f;&#xff1f;&#xff1f;&#xff1f; localStorage 1、生命周期&#xff1a;localStorage的生命周期是永久的&#xff0c;关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据&am…...

基于SpringBoot的在线视频教育平台的设计与实现

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线视频教育平台当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线视频教育平台&#xff0c;它彻底改变了过…...

Vue 2.0源码分析-渲染函数render

Vue 的 _render 方法是实例的一个私有方法&#xff0c;它用来把实例渲染成一个虚拟 Node。它的定义在 src/core/instance/render.js 文件中&#xff1a; Vue.prototype._render function (): VNode {const vm: Component thisconst { render, _parentVnode } vm.$options//…...

阿里云国际短信业务网络超时排障指南

选取一台或多台线上的应用服务器或选取相同网络环境下的机器&#xff0c;执行以下操作。 获取公网出口IP。 curl ifconfig.me 测试连通性。 &#xff08;推荐&#xff09;执行MTR命令&#xff08;可能需要sudo权限&#xff09;&#xff0c;检测连通性&#xff0c;执行30秒。 m…...

浅用tensorflow天气预测

1&#xff0e;开发环境 &#xff08;1&#xff09;Python3.8 &#xff08;2&#xff09;Anaconda3 &#xff08;3&#xff09;Tensorflow &#xff08;4&#xff09;Numpy &#xff08;5&#xff09;Pandas &#xff08;6&#xff09;Sklearn 先依次安装好上面的软件和包…...

基于SpringBoot学生读书笔记共享

摘 要 本论文主要论述了如何使用JAVA语言开发一个读书笔记共享平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述读书笔记共享平台的当前背景以及系统开发的…...

设计模式之装饰模式(2)--有意思的想法

目录 背景概述概念角色 基本代码分析❀❀花样重难点聚合关系认贼作父和认孙做父客户端的优化及好处继承到设计模式的演变过程 总结 背景 这是我第二次写装饰模式&#xff0c;这一次是在上一次的基础上进一步探究装饰模式&#xff0c;这一次有了很多新的感受和想法&#xff0c;也…...

深入了解 Pinia:现代 Vue 应用的状态管理利器

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…...

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 声学相关模型…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...