7 ms·
>the initial version of WebAssembly is a terrible target if your language relies on the presence of a garbage collector. Lack of GC was one of the appealing pa
by tjoff 4y ago
>the initial version of WebAssembly is a terrible target if your language relies on the presence of a garbage collector.
Lack of GC was one of the appealing parts of WASM to me. Keep it simple. It is good to be careful about utilizing memory on your visitors machines, so you better spend a lot of thought on memory management.
- wahern 4y agoIf the WASM module has no GC'able objects, then there'd be no reason for the GC to run. At least in theory. Certainly the 0 GC'able object case seems like an easy optimization.
- tjoff 4y agoYeah, but once GC is an option 99% of the sites you are going to visit will utilize it and use as much resources that they could ever "get away" with.
- remexre 4y agoIsn't it more likely that if there never was first-party GC, everyone who wants GC is just going to bundle a bad one instead, making those sites _slower_?
- evntdrvn 4y agoThat’s already happening with .NET, yeah
- wahern 4y agoMaybe. Everybody assumes that once WASM gets a GC framework that their favorite language, e.g. Python, will become a first-class citizen. But I suspect this won't come to pass for two related reasons: 1) There's no such thing as a universal GC. GC semantics differ across languages because the semantics matter; language developers make different choices. For example, some GCs support finalizers, others don't. Some with finalizers support resurrection, some don't; likewise, some languages specify a well-defined order for finalization (e.g. Lua defines it as the reverse order of allocation). 2) Similar to GC, there are other aspects that will prevent popular languages with complex runtimes from being compiled directly to WASM without altering language semantics or the runtime behavior relative to the standard, native environment. For example, eval. So even with GC, the choices will likely remain the same as they are now: if you want the full experience of your favorite, rapid-development language within the WASM virtual machine, you must incur runtime overhead, up to and including double virtualization. Or, alternatively, you must contend with a bifurcation in a language ecosystem--native semantics vs WASM semantics. This will all be compounded by how programmers typically treat even the slightest differences, compromises, or concessions in behavior or performance as ritual impurities to be shunned. Ultimately, I don't expect the current status quo changing--languages other than statically compiled, strongly typed, non-GC'd languages like C, C++, Rust, or similar seeing much more usage in WASM environments than they already do, either browser-side or server-side.
- wolpoli 4y agoWould this mean that we might end up with a new language that compiles to WebAssembly with GC? Logically, it would be statically type since anyone wanting a dynamically type language could just use Javascript.
- wahern 4y agoThere's already one ready and waiting: https://www.assemblyscript.org/ https://www.assemblyscript.org/
- kaba0 4y agoGraalVM’s Truffle project seems to get away quite well with a universal GC implementation. With it, one can create a competitively fast language-specific runtime simply by creating an AST-interpreter: so far the more complete ones being JS, Ruby, R, Python and even LLVM bitcode — all of them mapping to the JVM’s state-of-the-art GCs. This allows easy polyglot programs as well, where the JIT compiler can even optimize across language boundaries! I think that languages with more niche control flow/GC semantics should just accept the tradeoffs and find some other way around - which is not unheard of in case of WASM, if I’m not mistaken things like stack pointers also have limitations in WASM vs the native C world.
- mike_hearn 4y agoThat's possible partly because the Java GC featureset is nearly a superset of what other GC runtimes offer, and partly because Truffle/Graal integrate deeply with the JVM compilers for things like barriers.
- ianburrell 4y agoI think people don’t distinguish between static languages with GC and dynamic languages. Static languages will run well, they already compile to binary or bytecode. My guess is that Java and C# could compile to WebAssembly, or JIT or AOP would be relatively small. Dynamic languages need to read source and either interpret or JIT it. The result is much larger runtime and worse performance. It will probably always be worse than running JavaScript. A few people will want to use Python but it won’t be common.
- aseipp 4y agoExisting compilers for GC'd languages that target WebAssembly today have to use inefficient schemes to make their runtimes work, making the website slower than they would be otherwise, which is pretty much the entire point of OP. And anyway, regarding "lack of GC in WASM made it appealing" -- support for high level languages with GC semantics was always a long-term goal for WebAssembly and GC was thought about by the relevant parties long before the 1.0 spec was even ratified (the initial placeholders were added as early as 2017, 2 years before 1.0 ratification); it was just not within scope for the earlier versions because it's a pretty big topic, including many things that aren't even wholly GC related e.g. value types. But this isn't surprising either; most of the earliest implementations and concerned parties were browsers, and the interactions between WebAssembly and JavaScript's memory models, along with the popularity of Javascript-targeting compilers (which suffer from many similar contortions), meant that GC was always a pretty obvious "This is a thing we need to think about in the long run" feature.
- tjoff 4y agoWhich might/should prompt a rethink... You are correct, but I disagree with the premise. Javascript and the entire ecosystem is horrible and only came to rise because there was no other option. For the first time ever we do a have shot of making something better and our goal is to adapt it to the lowest common denominator? We most certainly don't make it easy for ourselves...
- illiarian 4y ago> Which might/should prompt a rethink It shouldn't. It's goal is to continue running in the browsers and to have proper interactions with browser objects like the DOM. And those are garbage-collected by the browser. So you need at least some GC support in wasm to tell it that an object is released and to check if the object is still held by wasm runtime. > and our goal is to adapt it to the lowest common denominator How is garbage collection the lowest common denominator?
- kaba0 4y agoAs opposed to running the litany of GCd javascript they do now?
- kevingadd 4y agoI don't understand this logic. If you take gc away the people who would leak using gc will leak using malloc instead. Unless you're actually proposing that those people shouldn't be allowed to ship software?
- lxgr 4y agoAs opposed to now, where they might be using even more memory because bring-your-own-GC solutions are that much more inefficient, as outlined in the article?
- quickthrower2 4y agoNot sure how that follows since JS exists and a lot of people are going to just build on a runtime anyway.
- haberman 4y agoI'm one of the biggest GC curmudgeons, but as long as it's an opt-in thing that you do not pay for when you do not use, I am happy. I speak as the kind of developer who wants to optimize the memory management.
- tjoff 4y agoAs a developer, absolutely! But as someone who uses the internet for browsing, strong disagree.
- h0l0cube 4y agoMost of what makes browsing slow is network latency. Each website is in essence a 'streamed' app.
- lxgr 4y agoI've definitely seen janky webapps with the jank persisting even after all resources are fetched. Modern JS engines are very fast, but developers are faster (in pulling in quadratically more dependencies, negating all performance improvements instantly).
- h0l0cube 4y agoAre you sure everything has been fetched and processed? Some times this happens dynamically. Compare jank to an electron app where all artifacts are preloaded and preprocessed. To balance that, I've also seen jank in native mobile apps where developers haven't properly used the background thread, or done something strange in interface builder where the constraints don't solve properly. > in pulling in quadratically more dependencies, negating all performance improvements instantly Adding a lot of dependencies will affect memory consumption which may have knock-on effects due to paging if your system is low on memory, but that aside it's what and how much code is executed per frame that matters to speed. Dynamic memory allocation and garbage collect are probably the culprits you're searching for, but improvements of javascript engines and framework libraries have largely negated this issue for most websites.
- RobotToaster 4y ago>so you better spend a lot of thought on memory management. The more probable outcome is stuff gets shipped with memory leaks since it isn't your server's memory it's eating.
- flohofwoe 4y agoA GC doesn't prevent memory leaks though (if you keep holding references to objects that are not actually needed anymore).
- kaba0 4y agoA GC does prevent leaking any unreachable objects, which is as good as it gets. Sure, if you store strong references to everything, nothing can be done, but that’s a trivially debuggable problem.
- flohofwoe 4y ago...which is also the most likely reason for a memory leak when you manage your memory through refcounting (or rather: with refcounting, memory leaks are just as unlikely as with a GC). But even without both, these days (with memory debuggers and profilers integrated into IDEs) pretty much all memory related problems are 'trivially debuggable', this stuff isn't as scary anymore as it was 20 years ago (e.g. Xcode's Instruments has a leak detector which lets you click on the line of code which caused a memory leak, and Visual Studio has similar features).
- kaba0 4y agoMemory leaks have never been scary in tracing GCs and they are not too scary in RC as well, though I would guess that cyclic references leaking is definitely a top 10 bug for swift and alia. Memory corruption has been/is the real issue.
- TheCoelacanth 4y agoI don't see how it would be possible to have good DOM interop from WASM without some form of GC accessible from WASM.
- mabbo 4y agoCounter-intuitively, I feel as though GC results in better memory usage in this situation. Option 1: you rely on every single developer to be careful and make no memory-leaking mistakes. Option 2: you take this problem out of the hands of the specific application devs and give it to experts in memory management, who write a GC. If this platform is going to be the future of distributed computing, just imagine the number of terrible devs who will be releasing their code upon you.
- rubatuga 4y agoYou can use reference counting memory management
- dreamcompiler 4y agoWhich is usually slower than a real gc and must punt to a real gc when you run out of counter space or have cycles.
- josephg 4y ago> Option 1: you rely on every single developer to be careful and make no memory-leaking mistakes. Nobody is expecting every single developer to carefully write their own garbage collector. WASM is a compilation target for other languages. The language you're compiling defines how memory management works, be that C / Zig (do it yourself), Rust (compile time borrow checker), Swift/ObjC (Rc / arc) or Go/JS/Java/C# (full garbage collector built into the language). For GCed languages like Go or C#, the design choice WASM makes is between: 1. The compiler injects its own garbage collector into the created webassembly modules, just like it does when compiling native binaries. or 2. The webassembly virtual machine provides a garbage collector that any compiled code can use. The benefit of (1) is that it makes webassembly virtual machines simpler and safer. (This is what the GP comment wants). (Also compilers can do language-specific optimizations to their own GC.) But (2) has a bunch of benefits too: - The GC can be higher performance (its not written in webassembly). - Interoperability between WASM bundles written in different languages is much better. Eg it'd be easier for Go in a WASM bundle to talk to JS in the browser. Or Go and C# code to interoperate via WASM. - The .wasm modules for GCed languages will be much smaller, since they don't need to compile in a garbage collector. The Go/Java/C# you write will be the same. The difference is who provides the garbage collector. Your compiler, or the WASM virtual machine?
- dreamcompiler 4y ago> It is good to be careful about utilizing memory on your visitors machines, so you better spend a lot of thought on memory management. Which is why Javascript has a gc.
- kg 4y agoFrequently the software running inside WASM sandboxes has its own garbage collector anyway, and it's not going to perform as well as a native host collector in some cases. Especially if you start doing cross-language GC in order to talk to the host (web browser) and manipulate its objects. Of course, exposing a WASM GC API that can actually meet the needs of real software is tough, which is why it didn't happen... If you think WASM software is going to be efficient with its memory usage, you should look closer at the memory model and take note of details like 'you can't ever shrink the heap' and 'you can't do read-only shareable mappings'
- lxgr 4y agoForce people to think a lot more about memory than they want to, and they'll just keep using whatever they currently use, which is probably not optimal for performance. It's not like there is any chance of a WASM-only future any time soon, and as long as it's competing with JavaScript (and Emscripten targeting it), there's a case to be made for it to be more accommodating.
- whitehexagon 4y ago>Lack of GC was one of the appealing parts of WASM to me. Same for me, especially paired with Zig where memory management is far more central to development. It's a shame the JS interfacing overhead is so high, and I think energy would be better spent improving that, rather adding bloat to WASM.