Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 806|回复: 1
打印 上一主题 下一主题

大内存地址空间

[复制链接]

1272

主题

2067

帖子

7962

积分

认证用户组

Rank: 5Rank: 5

积分
7962
跳转到指定楼层
楼主
发表于 2024-4-15 13:27:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
X86程序可用内存扩展方案
1、 进入菜单找到Visual Studio 2017菜单下的 适用于 VS 2017 的 x64 本机工具命令提示 的子菜单项,右键单击弹出菜单,选择更多,选择以管理员身份运行
2、 在当前dos窗口运行以下指令(扩展内存到4GB):
editbin /largeaddressaware C:\Users\hxx\Desktop\mCloud.exe
其中后面的文件路径是所需要扩展内存的exe文件绝对路径。(通常是安装目录下的主程序路径)
执行后,打印以下信息:
C:\Windows\System32>dumpbin /headers C:\yidongyunpan\mCloud\mCloud.exe
Microsoft (R) COFF/PE Dumper Version 14.16.27045.0
Copyright (C) Microsoft Corporation.  All rights reserved.
3、 查看指令是否已经成功执行,运行以下指令:
dumpbin /headers C:\Users\hxx\Desktop\mCloud.exe
其中后面的文件路径是所需要扩展内存的exe文件绝对路径。(通常是安装目录下的主程序路径)
没执行内存扩展前或执行指令不成功时候,会打印以下信息
FILE HEADER VALUES
             14C machine (x86)
               5 number of sections
        6311A64D time date stamp Fri Sep  2 14:44:29 2022
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
             102 characteristics
                           Executable
                                   32 bit word machine
        执行指令成功后,会打印一下信息:
FILE HEADER VALUES
            14C machine (x86)
              5 number of sections
       62FC9DFA time date stamp Wed Aug 17 15:51:22 2022
              0 file pointer to symbol table
              0 number of symbols
              E0 size of optional header
             122 characteristics
                              Executable
                      Application can handle large (>2GB) addresses
                                  32 bit word machine
https://www.cnblogs.com/bclshuai/p/15224204.html
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
1.问题描述
基于CEF(Chromium Embedded Framework)做了一个客户端网页浏览器,用于加载一些网页,有个车辆查询的网页,有很多的图片要加载显示,图片是分页展示的,每翻一页,内存就会增加一点,增加到800M时,进程会崩溃或者白屏。
2.问题分析
内存增加导致进程崩溃。
(1)CEF定时清除缓存
(2)前端控制翻页时清除上一页的图片数据
(3)增大CEF的最大内存上限。

3.解决办法
3.1设置vs2015大缓存编译属性---实测无效

3.2CefSettings settings设置本地缓存路径----实测无效
CefString(&settings.cache_path).FromString(strDumpPath);
CefString(&settings.root_cache_path).FromString(strDumpPath);
按照下面的参数说明,如果没有设置缓存路径则会在内存中进行缓存。
///
// The location where data for the global browser cache will be stored on
// disk. If this value is non-empty then it must be an absolute path that is
// either equal to or a child directory of CefSettings.root_cache_path. If
// this value is empty then browsers will be created in "incognito mode" where
// in-memory caches are used for storage and no data is persisted to disk.
// HTML5 databases such as localStorage will only persist across sessions if a
// cache path is specified. Can be overridden for individual CefRequestContext
// instances via the CefRequestContextSettings.cache_path value. When using
// the Chrome runtime the "default" profile will be used if |cache_path| and
// |root_cache_path| have the same value.
///
cef_string_t cache_path;
///
// The root directory that all CefSettings.cache_path and
// CefRequestContextSettings.cache_path values must have in common. If this
// value is empty and CefSettings.cache_path is non-empty then it will
// default to the CefSettings.cache_path value. If this value is non-empty
// then it must be an absolute path. Failure to set this value correctly may
// result in the sandbox blocking read/write access to the cache_path
// directory.
///
cef_string_t root_cache_path;
实际测试之后,会缓存一些文件,但是不会缓存图片,如下图所示,但是翻页还会加载图片到内存,内存不断增加,到了一定值后还是会崩溃。并不会达到减少内存占用的问题。

3.3SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);设置缓存到文件---实测无效
百度这个方法说是当程序内存占用过多,或者系统内存不够时,会将内存闲置不经常使用的缓存到本地文件。但是实测也无效;

3.4创建render渲染进程设置Application-cache参数------实测无效
CefBrowserSettings browser_settings;

browser_settings.application_cache = STATE_DISABLED;//禁用缓存
CefWindowInfo window_info;
window_info.SetAsPopup(NULL, "");
window_info.style &= ~WS_VISIBLE;
CefRefPtr<CefBrowser> b = CefBrowserHost::CreateBrowserSync(window_info, this, url, browser_settings, NULL,NULL);

3.5前端不去缓存上一页的图片---实测有效
前端去除采用懒加载方式去下载图片,翻一页不去缓存上一页的图片。
4.总结
最终方案是让前端去修改,去除懒加载方式,不在缓存上一页的图片数据。

回复

使用道具 举报

1272

主题

2067

帖子

7962

积分

认证用户组

Rank: 5Rank: 5

积分
7962
沙发
 楼主| 发表于 2024-4-15 13:46:41 | 只看该作者
为 .NET Core / Framework 程序开启大内存感知(LargeAddressAware),使 32 位程序支持最多 4GB 的用户空间内存
https://cloud.tencent.com/developer/article/2349824
如果你不做特殊处理,把你的项目以 x86 的架构进行编译,那么你的应用程序在 Windows 上最多只能使用 2GB 的内存(地址空间)。如果你的项目使用 .NET Framework 框架,那么现行有很多简单的方法来帮你实现大内存感知,但 .NET Core 框架下却没有。所以我写了一个库 dotnetCampus.LargeAddressAware,帮助你轻松实现 32 位程序的大内存感知。

dotnetCampus.LargeAddressAware 库
无论你是 .NET Framework 程序还是 .NET Core 程序,只要在你的项目中安装 dotnetCampus.LargeAddressAware 即可立享最高可达 4GB 的用户空间内存。
123


<ItemGroup>  <PackageReference Include="dotnetCampus.LargeAddressAware" Version="1.0.0" /></ItemGroup>



效果
应用程序


操作系统


是否开启大内存感知


最大可使用的用户空间内存



32-bit


32-bit




2GB



32-bit


64-bit




2GB



32-bit


32-bit


✔️


3GB



32-bit


64-bit


✔️


4GB



原理
我在 2017 年写的一篇博客(使 32 位程序使用大于 2GB 的内存)中就已经介绍过 32 位程序开启大内存感知的原理和方法了,不过因为一开始我自己也懂得不多,所以写得比较简单。后来也根据自己新的理解也填充了不少内容,但是当初取的标题和内容真的很难被搜到,而且侧重点在方法上。所以现在重写了现在的这篇新的,侧重在让懒用户快速上手,让深度用户快速理解上。
32 位寻址空间只有 4GB 大小,于是 32 位应用程序进程最大只能用到 4GB 的内存。然而,除了应用程序本身要用内存,操作系统内核也需要使用。应用程序使用的内存空间分为用户空间和内核空间,每个 32 位程序的用户空间可独享前 2GB 空间(指针值为正数),而内核空间为所有进程共享 2GB 空间(指针值为负数)。所以,32 位应用程序实际能够访问的内存地址空间最多只有 2GB。
在应用程序的 PE 头上,有一个应用程序是否感知大内存的标记 LARGEADDRESSAWARE。当 32 位操作系统识别到此标记时,会为其提供 3GB 的用户空间;当 64 位操作系统识别到此标记时,会为其提供 4GB 的用户空间,即用户态完全用满 32 位的寻址空间。
其他开启 LARGEADDRESSAWARE 的方法不推荐的方法:仅适用于 .NET Framework 的旧方法
当时的那篇博客中,我提到过可通过编译成 AnyCPU (Prefer 32-bit) 来实现大内存感知,这也是最简单的方式,被 .NET Framework 自带。方法是修改 csproj 文件,加上这两句:
12345


<PropertyGroup>++    <!-- 此方法被废弃,因为不支持 .NET Core -->++    <PlatformTarget>AnyCPU</PlatformTarget>++    <Prefer32Bit>true</Prefer32Bit>    </PropertyGroup>



可惜,此方法只适用于 .NET Framework 程序,不适用于 .NET Core 程序!因为 .NET Core 框架下编译时,是直接忽略 Prefer32Bit 的!.NET Core 下大内存感知确实是有了,但生成的却是 AMD64 程序,无法在 32 位系统下运行。



不推荐的方法:使用 EditBin 的原始方法
如果还想用自带的方法来完成大内存感知的开启的话,我们只能选用 Visual Studio 自带的 editbin 了。方法是打开 Visual Studio 自带的终端,然后在里面输入:
1


editbin /largeaddressaware xxx.exe



方法本身其实是非常好的,毕竟是 Visual Studio 自带的工具链。但需要手工执行就是一个大坑!你怎么能保证每次发布前要运行一下这个命令呢?
检查是否已开启大内存感知
我在之前的博客中提到可以使用 Visual Studio 自带的 dumpbin 工具来检查是否开启了大内存感知:
1


dumpbin /headers xxx.exe | more



但是,我们有更直观的 dnSpy 为什么还要用命令行来临时查看呢?相信你早就注意到前面我已经贴了一张 dnSpy 检查大内存感知的图了。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-26 07:09 , Processed in 0.061957 second(s), 19 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表