Live data from Hacker News

Golang's big miss on memory arenas

avittig.medium.com

151–157 of 157 posts

Re: Golang's big miss on memory arenas

#151
post #85

Earlier quoted context omitted.

> Go just isn’t the tool we thought for some jobs Go made it explicitly clear when it was released that it was designed to be a language that felt dynamically-typed, but with performance closer to statically-typed languages, for only the particular niche of developing network servers. Which job that needs to be a network server, where a dynamically-typed language is a appropriate, does Go fall short on? One thing tha…

I don’t know about that, it was called a systems language when it came out. By any common usage of the term, it’s definitely not that.

By the common usage of the term, it is most definitely a systems language.

Systems are the "opposite" of scripts. Scripts are programs that perform a one-off task and then exit. Systems are programs that run indefinitely to respond to events. We have scripting languages and we have systems languages. While all languages can ultimately be used for both workloads, different feature-sets gear a language towards one or the other. Go is does not exhibit the traits you'd expect of a scripting language.

This idea that Go isn't a systems language seems to stem from "Rustacians" living in the same different world which confused sum types with enums, where they somehow dreamed up that systems are low-level programs such as kernels. To be fair, kernels are definitely systems. They run indefinitely too. But a user land server program that runs continuously to serve requests is also a system as the term has been normally used.

Re: Golang's big miss on memory arenas

#152
post #151

Earlier quoted context omitted.

I don’t know about that, it was called a systems language when it came out. By any common usage of the term, it’s definitely not that.

By the common usage of the term, it is most definitely a systems language. Systems are the "opposite" of scripts. Scripts are programs that perform a one-off task and then exit. Systems are programs that run indefinitely to respond to events. We have scripting languages and we have systems languages. While all languages can ultimately be used for both workloads, different feature-sets gear a language towards one or t…

Long before Rust or Go existed, “systems languages” were commonly the ones you can write a whole system in to run on hardware, like C, Pascal or C++. I’m not opposed to that definition changing, but it certainly hadn’t when Go came out.

I agree that Rust enums should have been called unions, though.

Re: Golang's big miss on memory arenas

#153
post #151

Earlier quoted context omitted.

By the common usage of the term, it is most definitely a systems language. Systems are the "opposite" of scripts. Scripts are programs that perform a one-off task and then exit. Systems are programs that run indefinitely to respond to events. We have scripting languages and we have systems languages. While all languages can ultimately be used for both workloads, different feature-sets gear a language towards one or t…

Long before Rust or Go existed, “systems languages” were commonly the ones you can write a whole system in to run on hardware, like C, Pascal or C++. I’m not opposed to that definition changing, but it certainly hadn’t when Go came out. I agree that Rust enums should have been called unions, though.

While that does not match my memory, it works too. An assembly language is part of Go, so it fits among the languages you mention. The only constraint it imposes is your imagination (and what the hardware is capable of). However, it remains that "systems language" was caveated as being for network servers specifically. But no matter how you slice it, I think we can agree that Go isn't a scripting language, so it must be a systems language.

Rust does use enums under the hood in order to implement sum types, so the name as it is used within the language is perfectly valid. It's just not clear how that turned into nonsense like Go not having enums (which it does).

Re: Golang's big miss on memory arenas

#154
post #89

> One concern was that Arenas introduced “Use-After-Free” bugs, a classic C++ problem where you access memory after the arena has been cleared, causing a crash. In Rust, can the lifetime of objects be tied to that of the arena to prevent this? Asking as a C/C++ programmer with not much Rust experience.

Yes, or rather, the lifetime of references to the contained objects can be tied to the lifetime of references to the arena. E.g., the bumpalo crate [0] has two relevant methods, Bump::alloc(), which puts a value into the arena and gives you back a reference, and Bump::reset(), which erases everything from the arena. But Bump::reset() takes a &mut self, while Bump::alloc() takes a &self reference and gives back a &mut…

That's interesting that reset() wipes the lifetime of references. Good reading material too, thanks.

Re: Golang's big miss on memory arenas

#155
post #150
post #148

Earlier quoted context omitted.

> GOGC was introduced in Go 1.5 yes, that's quite literally what I meant by "GOGC has always been there". 1.5 was released 10 years ago, just 3 years after 1.0. So to summarize: there is one knob (that has been there from basically the beginning), plus a second one (if you squint hard enough: GOMAXMEM), and absolutely no plans to add further ones, or to add alternative GCs.

That would be since Go exists, literally.

The point is that no-one is thinking to add knobs, or allow alternative GCs.

Re: Golang's big miss on memory arenas

#156
post #111
post #86

There's a bunch of activity ongoing to make things better for memory allocation/collection in Go. GreenTeaGC is one that has already landed, but there are others like the RuntimeFree experiment that aims at progressively reduce the amount of garbage generated by enabling safe reuse of heap allocations, as well as other plans to move more allocations to the stack. Somehow concluding that "By killing Memory Arenas, Go…

That one is kind of interesting given the past criticism of Java and .NET having too many GCs and knobs. With time Go is also getting knobs, and turns out various GC algorithms are actually useful.

That past criticism was and is correct, proven by the fact new Java GCs like ZGC were deliberately designed to offer few knobs.

Go isn't getting any new knobs, there are only two; that's nothing compared to 100's of options that old Java GCs had. Completely incomparable.

> and turns out various GC algorithms are actually useful.

I don't know what you're trying to say here, but I think I know why — you don't know either. Stop spitballing.

There are no "various GC algorithms" at play here at all. There is just a new algorithm that performs better. You can read all about it here: https://go.dev/blog/greenteagc. It's not an optional alternative GC, but a successor.

Re: Golang's big miss on memory arenas

#157
post #50

A better route for something like Go IMO is to move to a compacting collector, this would allow them to move to a bump allocator like Java for super fast allocations and would make deallocation effectively "free" by only moving live objects. They may need to make it generational so they aren't constantly moving long lived objects, but that is a memory vs cpu trade off (could be one more GC flag?). If I recall, the pr…

> this would allow them to move to a bump allocator like Java for super fast allocations and would make deallocation effectively "free" by only moving live objects

Ah, you've been misled as well. Super fast allocations is a meme. Yes, the very act of allocating is fast, great. Just like tossing trash on the floor. Super fast. Now you have a pile of garbage on the floor that you need to clean up. How fast are you going to end up being after the clean up?

In a design space as tightly constrained as a GC you can't just make something fast. You have to trade off something else to get it. So now that you have sacrificed something to make the act of allocating fast, you've also encouraged programmers using your language to allocate willy-nilly—it's fast after all. Now the pile of garbage is rising at an alarming rate and your self-gimped GC has to deal with it all.

Making allocations fast is a positive feedback loop that degrades GC performance. You want allocations to be slow and to leverage the leeway from that tradeoff to get a faster GC. Moreover, this will provide backpressure to the entire package ecosystem to limit allocations, further improving performance.

Post reply on HN