Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request]: Provide builds without the memory cage #35241

Closed
3 tasks done
rconde01 opened this issue Aug 5, 2022 · 15 comments
Closed
3 tasks done

[Feature Request]: Provide builds without the memory cage #35241

rconde01 opened this issue Aug 5, 2022 · 15 comments

Comments

@rconde01
Copy link

rconde01 commented Aug 5, 2022

Preflight Checklist

Problem Description

The introduction of the memory cage presents some problems for my project. I accept that the electron project has decided the tradeoffs are best for most, but now I'm in the position of having to set up and maintain infrastructure to do custom electron builds on linux/mac/windows.

Proposed Solution

It would be great if the electron project could continue to provide an alternative package stream with pointer compression and sandboxing disabled rather than requiring multiple 3rd parties to implement this themselves.

Alternatives Considered

The alternative is that we (and other projects like us) all separately need to setup/maintain this infrastructure.

Additional Information

No response

@RaisinTen
Copy link
Contributor

RaisinTen commented Aug 8, 2022

The introduction of the memory cage presents some problems for my project.

Could you explain some of those problems? I was wondering if there is a way to solve those without disabling the memory cage / maintaining alternate builds.

FYI, there are ways to refactor your code to be compatible with the memory cage change - https://www.electronjs.org/blog/v8-memory-cage#i-want-to-refactor-a-node-native-module-to-support-electron-20-how-do-i-do-that, in case that's the problem you're facing.

@VerteDinde
Copy link
Member

Hey @rconde01, we discussed having separate builds for the v8 memory cage and ultimately decided against it. While we get some people may run into limitations with the memory cage, the maintenance costs (both financially and in maintainer time for bug fixing) just didn't make sense. Pointer compression is now a fundamental performance feature of V8; we wanted to stay mapped closely to upstream or we risk running into some gnarly edge cases.

You can read more of the discussion here (this started with pointer compression, but expanded into the memory cage as well): #31330 (comment)

I'll leave this issue open for a time to get more input from others, but I think it's unfortunately unlikely that we'll ship two different builds, or move away from the memory cage. If there are other ways we can make this easier for you as an app developer, we're open to hearing them!

@rconde01
Copy link
Author

I apologize I am ooo this week but I will respond ASAP

@rconde01
Copy link
Author

First question:
The blog post says:
"ArrayBuffers are counted separately from the rest of the V8 heap, but have their own limits"

But here @nornagon says " I do see experimentally that ArrayBuffer data isn't stored off the heap as I had guessed". So is the blog wrong, or was that comment later retracted. Also, it would be great to extract the details of the various limits for the docs. The dialog at the references chromium issue is a bit impenetrable.

@marcelblum
Copy link

@rconde01 that issue #31330 that I opened almost a year ago contains what has become a confusing jumble of (some wrong, some outdated) info gathered over many months, but I can try to answer based on the most recent findings. ArrayBuffer data is stored off heap and is not subject to the 4GB pointer compression heap limit. But it is still subject to Chromium platform-specific hardcoded per-process limits as discussed in that Chromium issue. Those limits are currently 16GB for Mac & Linux and 8GB for Windows. It appears that Chromium will be going ahead with raising the Windows limit to 16GB, which will trickle downstream to Electron, however even with that limit increased, as I understand it, Windows will still be limited to 8GB in each renderer process if sandboxing is on (now on by default). In Electron it's easy enough to disable sandboxing. But if you need >16GB, even if that Chromium change is merged in, as it stands you would still need to build your own Electron to increase/remove the 16GB limit.

@rconde01
Copy link
Author

Thanks @marcelblum ! We use node integration in the render process, so I think sandboxing must already be disabled there. 16 GB should probably be fine with us if it comes to windows. Then, the main issue is then the pointer sandboxing. We were definitely relying on the capability to wrap an off-heap pointer in an ArrayBuffer. I need to study a bit more whether it's critical for us.

@nkallen
Copy link

nkallen commented Sep 18, 2022

Hi, I'm also wrapping my head around this issue. I have lots of 3d mesh data stored off-heap and the memory cage is potentially a big problem for me. I can refactor some but not all of my native code to use Napi allocated buffers, but both the 8gb and 16gb limit are too small.

@ckerr
Copy link
Member

ckerr commented Sep 20, 2022

Since previous maintainer discussions have been against this idea and no maintainer has stepped up to champion the feature in the last month, I'm closing this ticket as per discussion in #35241 (comment)

@ggreco
Copy link

ggreco commented Oct 20, 2022

I would never had started using electron years ago if I thought such a limitation can go live.

Sharing memory between the native layer and the javascript world is the only feature electron has that you do not have using other similar frameworks. We will stick with electron 20 until is so obsolete that we will need to decide to fork electron 20 or fork electron-latest disabling memory cage (and possibily also pointer compression), when you share array buffers between the native world and the javascript world typically you are sharing things like video frames or huge datasets.

Electron is used to build client application most of these security concerns are not useful for a large part of the user base, and for those who runs remote javascript inside electron they should have additional flags like sandbox: true, nodeIntegration: false to enforce those behaviours...

@WillAvudim
Copy link

We are in the same boat as the rest of the folks. Our application uses nodeIntegration and we are extremely memory-heavy, loading all sorts of datasets for visualization and running inference on GPUs (we are primarily doing ML). Splitting it explicitly into a back-end and an electron front-end would be an infeasible massive rewrite with no benefits. In fact, in that case it would make more sense to dump Electron entirely and switch to web.

I hope, at the very least, we could get a memory cage-free build from time to time, even if it's once in every few years.

Sticking to version 20 indefinitely for now.

If anyone is aware of a recent electron build without memory caging (and pointer compression), please post a link.

@nkallen
Copy link

nkallen commented Jan 4, 2023

I am waiting to upgrade but my plan eventually is to have two memory zones, a hotter one inside the cage and a colder one outside the cage, copying when necessary. Annoying but not outrageous.

It's funny you mention nodeIntegration because the developers of VSCode mentioned "Blocking Node.js from renderer processes is an encouraged Electron security recommendation and will eventually be the only way of writing Electron applications. " https://code.visualstudio.com/blogs/2022/11/28/vscode-sandbox

If that is in fact true, the only way to access a native module would be over IPC, meaning a high-overhead async API for EVERYTHING. Electron would certainly be a poor technology choice for any application that's not basically a frameless website: wasm and js only. At that point, it would be insane to use Electron for a lot of the things it is currently being used for. It's a shame because, while Electron has its downsides, nothing else has emerged as good replacement for cross-platform native GUI apps.

@ggreco
Copy link

ggreco commented Jan 5, 2023

The only reason we choose electron when designing our architecture was the possibility to hook native code (and share his memory) in the renderer process...
This focus on web-like security in the last two years or so for electron is IMHO out of scope, since most of the users want to run a LOCAL web UI on the application, not some unsafe web site...

If that is the plan (removing node from the renderer) using a native webview widget in a QT application will be as effective as electron... with far less limitations.

@rconde01
Copy link
Author

rconde01 commented Jan 6, 2023

I am waiting to upgrade but my plan eventually is to have two memory zones, a hotter one inside the cage and a colder one outside the cage, copying when necessary. Annoying but not outrageous.

It's funny you mention nodeIntegration because the developers of VSCode mentioned "Blocking Node.js from renderer processes is an encouraged Electron security recommendation and will eventually be the only way of writing Electron applications. " https://code.visualstudio.com/blogs/2022/11/28/vscode-sandbox

If that is in fact true, the only way to access a native module would be over IPC, meaning a high-overhead async API for EVERYTHING. Electron would certainly be a poor technology choice for any application that's not basically a frameless website: wasm and js only. At that point, it would be insane to use Electron for a lot of the things it is currently being used for. It's a shame because, while Electron has its downsides, nothing else has emerged as good replacement for cross-platform native GUI apps.

FYI:
https://twitter.com/rccola3000/status/1610710713550487556

@nkallen
Copy link

nkallen commented Jan 8, 2023

That's a relief. He says it was a mistake.

@ymeine
Copy link

ymeine commented Dec 27, 2023

Given the position of the Electron team regarding that topic, it seems that currently there is no other choice than maintaining a build elsewhere.

I wrote in this comment #10409 (comment) how I made a custom build, if anyone was, like me, a bit stuck wondering how to do it.

DISCLAIMER: I can't be sure the generated build has no issues due to the changes, since I haven't had the time to test it a lot (I just tested the ArrayBuffer external buffer feature). But if we think about the scope of the change, there shouldn't be any: sandboxing and pointers compression are options in the build, so the code must accommodate opting out of them. Also, it should be something purely internal to V8, so neither Chromium nor Node.js should consider those features are enabled or disabled. But again, I'm not sure of anything, it's just my intuition built over the years through experience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants