更多精彩内容,欢迎观看:
如何排查 Electron V8 引发的内存 OOM 问题(上):https://developer.aliyun.com/article/1263250?spm=a2c6h.13148508.setting.14.1e7f4f0e2Cy18t
如何通过编译 Electron 源码提升 v8 堆内存上限
为了突破 v8 堆内存上限,我们需要重新编译 Electron 源码,下面会详细介绍如何编译出一个提升 v8 堆内存上限的 Electron 版本。
▐ 构建前配置科学上网环境
首先需要确保电脑系统具备如下环境:
- 科学上网环境
- Visual Studio 2019 版本(推荐版本)
- Node.js(建议使用最新稳定版本)
- Git(建议使用最新稳定版本)
- Python3(推荐版本)
- Debugging Tools for Windows of Windows SDK(根据电脑系统的实际情况确定使用哪个版本)
- 卸载 nvm 工具(如果有安装的话)
- 至少 25 GB 的磁盘空间剩余
准备好这些环境后,接着通过 git 命令下载谷歌提供的 depot_tools 工具:
> git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
我们也可以通过谷歌提供的下载地址下载该工具,下载完成后把压缩包解压到 D:\depot_tools 目录(具体路径可以自行设置),确保该目录下存在 .git 子目录和 gclient.bat 批处理文件才行。
然后在系统环境变量中增加 depot_tools 的目录路径(注意这个路径必须在所有其他环境变量之前),如下图所示:
接着再增加下面 5 个系统环境变量:
DEPOT_TOOLS_WIN_TOOLCHAIN: 0DEPOT_TOOLS_DIR: D:\depot_toolsGIT_CACHE_PATH: D:\.gitCachehttp_proxy: http://127.0.0.1:13658https_proxy: http://127.0.0.1:13658
- DEPOT_TOOLS_WIN_TOOLCHAIN:使 depot_tools 工具不下载 Visual Studio 工具链(否则 depot_tools 将会下载一个只有谷歌内部员工才有权限使用的 Visual Studio,做此设置的前提是需要自己安装好 Visual Studio 开发工具)。
- GIT_CACHE_PATH:设置 git 的缓存目录,由于构建过程中需要下载大约 10 GB 的源码及资源文件,因此要防备网络断开、下载失败等情况,如果团队中其他成员也需要构建 Electron,那可以考虑共享 git 的缓存目录来提升构建效率。
- http_proxy / https_proxy:为 Python 提供科学上网的支持。
最后还需要为一系列的工具配置科学上网的环境:
控制台输入下面指令设置 git 的科学上网环境,注意端口号以电脑系统配置的代理端口号为准。
> git config --global https.proxy http://127.0.0.1:13658> git config --global http.proxy http://127.0.0.1:13658
控制台输入下面指令设置 node.js 的科学上网的环境,注意端口号以电脑系统配置的代理端口号为准。
> npm config set proxy=http://127.0.0.1:13658> npm config set https-proxy http://127.0.0.1:13658
控制台输入下面指令设置 gclient 的代理,注意端口号以电脑系统配置的代理端口号为准。
> set http_proxy=http://127.0.0.1:13658> set https_proxy=http://127.0.0.1:13658
控制台输入下面指令设置 winhttp 的代理,注意端口号以电脑系统配置的代理端口号为准。
> C:\Windows\system32>netsh> netsh>winhttp> netsh winhttp>> netsh winhttp>set proxy http://127.0.0.1:13658
▐ 构建不同版本的 Electron
当构建依赖的工具都配置好科学上网的环境后,就可以开始构建 Electron 源码了。接下来会分别介绍如何构建 nightly、release、debug、突破 V8 堆内存上限等不同版本的 Electron。
- 构建 nightly 版本的 Electron
首先创建一个目录,然后在该路径下用管理员的身份启动命令行工具 cmd.exe(不能使用 PowerShell、cygwin、Git Bash 等工具) 执行下面 3 个指令,用来初始化编译环境并同步 Chromium、Electron 和 node.js 的代码及其相关依赖。
> gclient config --name "src/electron" --unmanaged https://github.com/electron/electron> gclient sync --with_branch_heads --with_tags> gclient sync -f
因为 gclient 要下载 Chromium、Electron、node.js 等源码及资源文件与构建工具,所以这个过程非常漫长,请耐心等待。如果执行 "gclient sync --with_branch_heads --with_tags" 指令时遇到了下载 dugite(用于构建 Git 版本的工具)失败的问题,可以自行下载压缩包后放在当前目录下,然后再重新执行上述指令。
Downloading Git from: https://github.com/desktop/dugite-native/releases/download/v2.29.3-2/dugite-native-v2.29.3-3d467be-windows-x64.tar.gzError raised while downloading https://github.com/desktop/dugite-native/releases/download/v2.29.3-2/dugite-native-v2.29.3-3d467be-windows-x64.tar.gz GotError [RequestError]: read ECONNRESET at ClientRequest.<anonymous> (D:\workspace\electron\src\electron\node_modules\dugite\node_modules\got\source\request-as-event-emitter.js:178:14) at Object.onceWrapper (node:events:628:26) at ClientRequest.emit (node:events:525:35) at ClientRequest.origin.emit (D:\workspace\electron\src\electron\node_modules\dugite\node_modules\@szmarczak\http-timer\source\index.js:37:11) at TLSSocket.socketErrorListener (node:_http_client:481:9) at TLSSocket.emit (node:events:513:28) at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) at processTicksAndRejections (node:internal/process/task_queues:83:21) { code: 'ECONNRESET', host: 'github.com', hostname: 'github.com', method: 'GET', path: '/desktop/dugite-native/releases/download/v2.29.3-2/dugite-native-v2.29.3-3d467be-windows-x64.tar.gz', socketPath: undefined, protocol: 'https:', url: 'https://github.com/desktop/dugite-native/releases/download/v2.29.3-2/dugite-native-v2.29.3-3d467be-windows-x64.tar.gz', gotOptions: { path: '/desktop/dugite-native/releases/download/v2.29.3-2/dugite-native-v2.29.3-3d467be-windows-x64.tar.gz', protocol: 'https:', slashes: true, auth: null, host: 'github.com', port: null, hostname: 'github.com', hash: null, search: null, query: null, pathname: '/desktop/dugite-native/releases/download/v2.29.3-2/dugite-native-v2.29.3-3d467be-windows-x64.tar.gz', href: 'https://github.com/desktop/dugite-native/releases/download/v2.29.3-2/dugite-native-v2.29.3-3d467be-windows-x64.tar.gz', retry: { retries: [Function (anonymous)], methods: [Set], statusCodes: [Set], errorCodes: [Set] }, headers: { 'user-agent': 'dugite', accept: 'application/octet-stream', 'accept-encoding': 'gzip, deflate' }, hooks: { beforeRequest: [], beforeRedirect: [], beforeRetry: [], afterResponse: [], beforeError: [], init: [] }, decompress: true, throwHttpErrors: true, followRedirect: true, stream: true, form: false, json: false, cache: false, useElectronNet: false, secureProtocol: 'TLSv1_2_method', method: 'GET' }}
等控制台输出下面的结果后,表明上述指令已执行完成。
Operation completed over 1 objects/69.2 MiB.Hook 'python3 src/tools/update_pgo_profiles.py --target=win32 update --gs-url-base=chromium-optimization-profiles/pgo_profiles' took 20.10 secsRunning hooks: 62% (86/137) Fetch PGO profiles for win64________ running 'python3 src/tools/update_pgo_profiles.py --target=win64 update --gs-url-base=chromium-optimization-profiles/pgo_profiles' in 'D:\workspace\electron'Copying gs://chromium-optimization-profiles/pgo_profiles/chrome-win64-main-1672768604-8da543c818b6aea3eae2ad5cb80cfe61abd454a1.profdata...Downloading to temp gzip filename D:\workspace\electron\src\chrome\build\pgo_profiles\chrome-win64-main-1672768604-8da543c818b6aea3eae2ad5cb80cfe61abd454a1.profdata_.gztmpUncompressing temporarily gzipped file to D:\workspace\electron\src\chrome\build\pgo_profiles\chrome-win64-main-1672768604-8da543c818b6aea3eae2ad5cb80cfe61abd454a1.profdata...\ [1 files][ 68.5 MiB/ 68.5 MiB] 7.2 MiB/sOperation completed over 1 objects/68.5 MiB.Hook 'python3 src/tools/update_pgo_profiles.py --target=win64 update --gs-url-base=chromium-optimization-profiles/pgo_profiles' took 21.92 secsRunning hooks: 67% (93/137) style_perftest_files________ running 'python3 src/third_party/depot_tools/download_from_google_storage.py --no_auth --quiet --bucket chromium-style-perftest -d src/third_party/blink/renderer/core/css/perftest_data' in 'D:\workspace\electron'NOTICE: You have PROXY values set in your environment, but gsutilin depot_tools does not (yet) obey them.Also, --no_auth prevents the normal BOTO_CONFIG environmentvariable from being used.To use a proxy in this situation, please supply those settingsin a .boto file pointed to by the NO_AUTH_BOTO_CONFIG environmentvariable.Hook 'python3 src/third_party/depot_tools/download_from_google_storage.py --no_auth --quiet --bucket chromium-style-perftest -d src/third_party/blink/renderer/core/css/perftest_data' took 81.51 secsRunning hooks: 100% (137/137), done.
接着再执行下面的指令,此时会在 src/out/Testing(Testing 名称可以更改,但 src/out 子目录不能更改) 子目录内生成一个测试配置文件夹,然后我们会使用这个文件夹下的 testing.gn 构建脚本来构建 Electron 源码。
> cd src> set CHROMIUM_BUILDTOOLS_PATH=%cd%\buildtools> gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\")"
如果执行上述指令时遇到下面报错信息,可以直接看解决方法。
若 gn 没找到 src/buildtools 的路径,则解决方法如下:
- 检查环境变量 CHROMIUM_BUILDTOOLS_PATH 的值是否为 src 目录下 buildtools 的路径。
- 在 src 的上一级目录保留 .gclient 和 .gclient_entries 文件。
gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\")"gn.py: Could not find checkout in any parent of the current path.This must be run inside a checkout.
若安装的 Windows 10 SDK 版本不匹配,解决方法如下:
Traceback (most recent call last): File "D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py", line 315, in <module> main() File "D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py", line 273, in main env = _LoadToolchainEnv(cpu, toolchain_root, win_sdk_path, target_store) File "D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py", line 189, in _LoadToolchainEnv return _ExtractImportantEnvironment(variables) File "D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py", line 67, in _ExtractImportantEnvironment raise Exception(Exception: Path "C:\Program Files (x86)\Windows Kits\10\include\10.0.20348.0\shared" from environment variable "include" does not exist. Make sure the necessary SDK is installed.ERROR at //build/toolchain/win/toolchain.gni:500:24: Script returned non-zero exit code. win_toolchain_data = exec_script("//build/toolchain/win/setup_toolchain.py", ^----------Current dir: D:/workspace/electron/src/out/Testing/Command: D:/workspace/depot_tools/bootstrap-2@3_8_10_chromium_26_bin/python3/bin/python3.exe D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community" "C:\Program Files (x86)\Windows Kits\10" "C:\Windows\System32;C:\Windows\SysWOW64;Arm64Unused" win x86 environment.x86Returned 1.See //build/toolchain/win/BUILD.gn:34:3: whence it was called. win_toolchains("x86") { ^----------------------See //BUILD.gn:83:1: which caused the file to be included.group("gn_all") {
首先打开 Visual Studio Installer(该工具跟 Visual Studio 一起安装),然后点击“修改”按钮,如下图所示:
接着选择单个组件,把报错信息中提示要安装的 Windows 10 SDK(注意版本号)勾选上并点击“修改”按钮进行安装:
由于 Visual Studio Installer 安装的 Windows 10 SDK 不包含 Debugging Tools for Windows,所以安装完成后还不能继续执行指令 。我们还要打开系统设置中的“应用和功能”选项并找到刚刚安装的 Windows 10 SDK,点击“修改”按钮后在弹出界面中选择 Change 选项并点击 Next 按钮,选中 Debugging Tools for Windows,然后点击 Change 按钮。
若报了 "AssertionError: user32.lib is not found in LIB" 的错误,则解决方法如下:
Traceback (most recent call last): File "D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py", line 314, in <module> main() File "D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py", line 274, in main vc_lib_um_path = FindFileInEnvList(env, 'LIB', ';', 'user32.lib') File "D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py", line 212, in FindFileInEnvList assert optional, "%s is not found in %s:\n%s\nCheck if it is installed." % (AssertionError: user32.lib is not found in LIB:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x64C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64C:\Program Files (x86)\Windows Kits\10\lib\10.0.20348.0\ucrt\x64C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64Check if it is installed.ERROR at //build/config/win/BUILD.gn:310:27: Script returned non-zero exit code. vcvars_toolchain_data = exec_script("../../toolchain/win/setup_toolchain.py", ^----------Current dir: D:/workspace/electron/src/out/Release/Command: D:/workspace/depot_tools/bootstrap-2@3_8_10_chromium_26_bin/python3/bin/python3.exe D:/workspace/electron/src/build/toolchain/win/setup_toolchain.py "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community" "C:\Program Files (x86)\Windows Kits\10" "C:\Windows\System32;C:\Windows\SysWOW64;Arm64Unused" win x64 noneReturned 1.See //build/config/BUILDCONFIG.gn:437:35: which caused the file to be included. default_executable_configs += [ "//build/config/win:cfi_linker" ]
把 src\build\toolchain\win\setup_toolchain.py 第178 行的 Windows 10 SDK 版本 "10.019041.0" 修改为我们刚刚安装的 "10.0.20348.0" 版本即可。
经过这些步骤修改完成后,就可以继续执行上述指令了。执行成功后再执行下面的指令就开始正式构建 Electron 源码,由于这个指令要编译链接 4 万多个文件,因此会花费更长的时间。建议可以在睡觉前跑该指令,等第二天醒来就可以在 src/out/Testing 目录下找到我们自己编译生成的 electron.exe 可执行程序及相关的二进制资源了。
> ninja -C out/Testing electron -j 4
- 构建 release 版本的 Electron
在上一章节中,我们使用 build/args/testing.gn 脚本构建了 Electron 源码,然后在 src/out/Testing 目录下就会生成非常多的 dll、lib、exe 等文件。由于 Chromium 项目极其庞大,编译、链接工作往往需要耗费大量的时间,于是 Chromium 引入了分块构建的技术,将每个模块作为单独的动态库进行构建,这样就能大大加快编译、链接的速度。
我们除了可以使用 build/args/testing.gn 构建 Electron 源码外,还可以使用 build/args/release.gn 脚本构建 release 版本的 Electron。通过下面指令编译、链接 Electron 源码后,src\out\Release 目录下就会输出 release 版本的 Electron 编译结果。
> cd src> set CHROMIUM_BUILDTOOLS_PATH=%cd%\buildtools> gn gen out/Release --args="import(\"//electron/build/args/release.gn\")"> ninja -C out/Release electron -j 4
默认情况下,在编译前 gclient 获取的是 nightly 分支的 Electron 源码,获取源码的指令如下:
> gclient config --name "src/electron" --unmanaged https://github.com/electron/electron> gclient sync --with_branch_heads --with_tags
这是 Electron 开发团队日常工作时使用的分支,而我们一般需要 main 分支或 18-x-y 这种具体某个版本的分支,因此需要通过下面 git 命令来切换 src/electron 目录下的分支:
切换 main 分支
> cd src/electron> git remote remove origin> git remote add origin https://github.com/electron/electron> git checkout main> git branch --set-upstream-to=origin/main> git pull
切换 18-x-y 分支
> cd src/electron> git remote remove origin> git remote add origin https://github.com/electron/electron> git checkout 18-x-y> git branch --set-upstream-to=origin/18-x-y> git pull
切换完 Electron 源码分支后,务必执行下面的命令拉取新 Electron 源码分支所依赖的 Chromium、node.js 等源码(gclient 会检查 src/electron 目录下的 DEPS 文件,从中获取依赖信息)。
> gclient sync -f
接着再使用 “ninja -C out\Release electron -j 4” 指令就可以编译我们期望的某个版本分支(如 18-x-y 分支)的 Electron 版本了。若编译过程遇到下面报错信息,可以直接看解决方法。
若报了 "To rebaseline" 的错误,可能与 XFG(eXtended Flow Guard:拓展控制流防护)有关,按照提示执行 copy 命令即可。
To rebaseline: copy /y C:\Users\kelai\AppData\Local\Temp\tmpgx2zcmac\* D:\workspace\electron\src\third_party\win_build_output\midl\third_party\isimpledom\ISimpleDOMDocument.idl\x64ninja: build stopped: subcommand failed.
若报了 "error: use of undeclared identifier 'PROC_THREAD_ATTRIBUTE_COMPONENT_FILTER'" 的错误,则打开 src\sandbox\win\src\startup_information_helper.cc 文件并注释掉 131 行的 if 语句块代码(不要注释 "expected_attributes--;" 这一行代码,否则处理属性时会出错)。
../../sandbox/win/src/startup_information_helper.cc(132,13): error: use of undeclared identifier 'PROC_THREAD_ATTRIBUTE_COMPONENT_FILTER' PROC_THREAD_ATTRIBUTE_COMPONENT_FILTER, &component_filter_, ^1 error generated.[7/24935] CXX obj/components/paint_preview/common/mojom/mojom/paint_preview_recorder.mojom.objninja: build stopped: subcommand failed.
若报了 "error: enumeration value 'D3D_FEATURE_LEVEL_12_2' not handled in switch [-Werror,-Wswitch]" 的错误,是因为 D3D_FEATURE_LEVEL_12_2 是在 10.0.20170.0 的 SDK 中才添加进来,需要做如下修改:
../../gpu/ipc/common/device_perf_info_mojom_traits.cc(16,11): error: enumeration value 'D3D_FEATURE_LEVEL_12_2' not handled in switch [-Werror,-Wswitch] switch (d3d_feature_level) { ^~~~~~~~~~~~~~~~~1 error generated.[939/19937] ACTION //third_party/blink/public/mojom:mojom_platform__generator(//build/toolchain/win:win_clang_x64)ninja: build stopped: subcommand failed.
首先打开 src\gpu\ipc\common\device_perf_info_mojom_traits.cc 文件在第 37 行添加下面代码:
接着打开 src\gpu\ipc\common\device_perf_info_mojom_traits.cc 文件在第 79 行添加下面代码:
最后打开 src\gpu\ipc\common\device_perf_info.mojom 文件在第 84 行添加下面代码:
若报了 "error: enumeration value 'AudioEffectType_FarFieldBeamForming' not handled in switch [-Werror,-Wswitch]" 的错误,则打开 src\media\audio\win\audio_low_latency_input_win.cc 文件第 195 行添加下面代码:
../../media/audio/win/audio_low_latency_input_win.cc(158,11): error: enumeration value 'AudioEffectType_FarFieldBeamForming' not handled in switch [-Werror,-Wswitch] switch (type) { ^~~~1 error generated.[2536/19159] CXX obj/media/formats/formats/dts_stream_parser.objninja: build stopped: subcommand failed.
若报了 "error: redefinition of '_DXVA_*_AV1'" 的错误,则打开 src\media\gpu\windows\d3d11_AV1_accelerator.cc 文件并删除两个 #pragma 及之间的所有内容:
../../media/gpu/windows/d3d11_av1_accelerator.cc(273,16): error: redefinition of '_DXVA_Tile_AV1'typedef struct _DXVA_Tile_AV1 { ^C:\Program Files (x86)\Windows Kits\10\include\10.0.20348.0\um\dxva.h(1745,16): note: previous definition is heretypedef struct _DXVA_Tile_AV1 { ^3 errors generated.[1274/16624] CXX obj/media/gpu/gpu/d3d11_h264_accelerator.objninja: build stopped: subcommand failed.
解决完编译过程遇到的上面几个问题后,继续编译直到控制台输出 "STAMP obj/electron/electron.stamp" 日志时才表明编译成功,并且也会在 src\out\Release 目录下生成很多无用的文件,如下图所示:
其实,我们只要按照 Electron 团队发布的文件(参照 node_modules\electron\dist 目录下的文件)从 src\out\Release 目录下挑选出来即可,最终分发给用户的也只是这些文件,其他文件都是不需要的。
接下来我们开始介绍如何构建突破 v8 堆内存上限的 Electron 版本。
- 构建突破 v8 堆内存上限的 Electron 版本
早在 2014 年,Chrome 为了更好的安全性、稳定性和性能,就把 32 位进程切换为 64 位进程。但这样带来的副作用是每个指针从 4 个提升到 8 个字节,导致消耗了更多的内存。数据显示,在桌面端应用中 v8 占 Chrome 渲染器进程内存消耗的 60%。因此,v8 一直努力减少内存开销,在 v9.2 版本时通过将 64 位指针分为两半(其中高 32 位是基数,低 32 位是该基数的索引)来实现指针压缩,以尝试尽可能多地取回浪费的 4 个字节。
|----- 32 bits -----|----- 32 bits -----|Pointer: |________base_______|_______index_______|
其中 v8 实现指针压缩的源码分析如下所示:
- 首先打开 src\third_party\electron_node\deps\v8\BUILD.gn 文件,默认 v8_enable_pointer_compression 和 v8_enable_pointer_compression_shared_cage 变量为空,若 v8_current_cpu 为 64位(arm64 是 arm 中 64 位体系结构,x64 是 x86 系列中的 64 位体系结构,如下图电脑是 x64)则 v8_enable_pointer_compression 和 v8_enable_pointer_compression_shared_cage 变量都被赋值为 true,然后 enabled_external_v8_defines 新增 V8_COMPRESS_POINTERS 的定义。
# Enable pointer compression (sets -dV8_COMPRESS_POINTERS).v8_enable_pointer_compression = ""v8_enable_pointer_compression_shared_cage = ""v8_enable_31bit_smis_on_64bit_arch = false if (v8_enable_pointer_compression == "") { v8_enable_pointer_compression = v8_current_cpu == "arm64" || v8_current_cpu == "x64"}if (v8_enable_pointer_compression_shared_cage == "") { v8_enable_pointer_compression_shared_cage = v8_enable_pointer_compression} if (v8_enable_pointer_compression) { enabled_external_v8_defines += [ "V8_COMPRESS_POINTERS" ] if (v8_enable_pointer_compression_shared_cage) { enabled_external_v8_defines += [ "V8_COMPRESS_POINTERS_IN_SHARED_CAGE" ] } else { enabled_external_v8_defines += [ "V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE" ] }}if (v8_enable_pointer_compression || v8_enable_31bit_smis_on_64bit_arch) { enabled_external_v8_defines += [ "V8_31BIT_SMIS_ON_64BIT_ARCH" ]}
- 接着打开 src\third_party\electron_node\deps\v8\include\v8-internal.h 文件,因为前面定义了 V8_COMPRESS_POINTERS,那么 kApiTaggedSize 就会等于 4个字节大小的 kApiInt32Size(否则等于系统指针大小,cpu x64 则为 8 个字节大小),这就是 v8 实现指针压缩的原理。
/** * Configuration of tagging scheme. */const int kApiSystemPointerSize = sizeof(void*);const int kApiDoubleSize = sizeof(double);const int kApiInt32Size = sizeof(int32_t);const int kApiInt64Size = sizeof(int64_t); #ifdef V8_COMPRESS_POINTERSstatic_assert( kApiSystemPointerSize == kApiInt64Size, "Pointer compression can be enabled only for 64-bit architectures");const int kApiTaggedSize = kApiInt32Size;#elseconst int kApiTaggedSize = kApiSystemPointerSize;#endif
经过指针压缩后显著减少了内存消耗并提高了性能,但代价是 v8 将同一个进程中所有线程所使用的堆内存大小限制为 4GB。由于 Electron 对外发布版本默认打开了指针压缩,为了突破 v8 申请的堆内存上限,我们需要设置参数禁止指针压缩,并重新编译 Electron 版本,具体操作步骤如下:
首先打开 src\electron\build\args\all.gn 文件,添加下面的代码:
# Disable pointer compressionv8_enable_pointer_compression = falsev8_enable_pointer_compression_shared_cage = false
接着打开 src\third_party\electron_node\deps\v8\BUILD.gn 文件,把 v8_enable_pointer_compression 和 v8_enable_pointer_compression_shared_cage 变量都赋值为 false,关闭指针压缩功能。
最后在控制台执行下面指令重新编译 Electron 版本,等编译成功后 v8 就能突破 4GB 堆内存大小限制了。
> cd src> set CHROMIUM_BUILDTOOLS_PATH=%cd%\buildtools> gn gen out/Release_disable_v8_pointer_compression --args="import(\"//electron/build/args/release.gn\")"> ninja -C out/Release_disable_v8_pointer_compression electron -j 4
默认情况下,64 位操作系统 v8 可以申请 8GB 堆内存。我们可以打印 performance.memory 看下 v8 堆内存最大可申请大小,如下所示:
▐ 构建后清除代理设置
构建完成后,如果你想要清除掉前面为代理做的一系列设置,可以执行如下命令:
清除 git 代理:
> git config --global --unset http.proxy> git config --global --unset https.proxy
清除 npm 代理:
> npm config delete proxy> npm config delete https-proxy
清除 gclient 代理:
> set http_proxy=> set https_proxy=
清除系统代理:
> C:\Windows\system32>netsh> netsh>winhttp> netsh winhttp>> netsh winhttp>reset proxy
更多精彩内容,欢迎观看:
如何排查 Electron V8 引发的内存 OOM 问题(下):https://developer.aliyun.com/article/1263248?groupCode=taobaotech