Live data from Hacker News

Go does not need a Java-style GC

erik-engheim.medium.com

151–160 of 226 posts

Re: Go does not need a Java-style GC

#151
post #148

Earlier quoted context omitted.

C# makes it possible to do C (not C++) like memory management but it does not make it easy. Unsafe C# code is really, really, really unsafe, much more unsafe than equivalent C code, and does not compose well. It's improving, with Span/Memory, etc, but it remains an absolute last resort.

C and C++ memory managements are alike, C# doesn't need reference counted library types. If you mean RAII, they can be easily done with IDisposable, using and Rosylin analysers that throw errors when usings are forgotten. And yes, manually memory management should be last resource, proven by profiler data.

I do mean RAII, which is fundamental to C++. Memory management without it is not "C++ like".

IDisposable is not a substitute for RAII, and C# has nothing that can manage ownership in equivalent ways as it lacks deterministic destruction. Implementing, for example, a data structure based on unmanaged memory in C# in such a way that it can be safely used by code outside the library without undermining the safety of the language (i.e. without introducing the possibility of programming errors outside the data structure implementation causing leaks or memory corruption) is an exercise in discipline and requires a thorough understanding of the runtime - eg. knowing that an object can be garbage collected while a method on it is executing. I know this because I've done it (as a last resort after extensive profiling and production use of various optimised, managed versions of the library).

Re: Go does not need a Java-style GC

#152
post #10

Cool article, I'm not sure I agree with the headline. I used to write low-scale Java apps, and now I write memory intensive Go apps. I've often wondered what would happen if Go did have a JVM style GC. It's relatively common in Go to resort to idioms that let you avoid hitting the GC. Some things that come to mind: * all the tricks you can do with a slice that have two slice headers pointing to the same block of memo…

Object pooling used to be more common in Java. Now it is mainly used for objects that are expensive (incurs latency) to create, not for GC reasons.

Re: Go does not need a Java-style GC

#153
post #148

Earlier quoted context omitted.

C and C++ memory managements are alike, C# doesn't need reference counted library types. If you mean RAII, they can be easily done with IDisposable, using and Rosylin analysers that throw errors when usings are forgotten. And yes, manually memory management should be last resource, proven by profiler data.

I do mean RAII, which is fundamental to C++. Memory management without it is not "C++ like". IDisposable is not a substitute for RAII, and C# has nothing that can manage ownership in equivalent ways as it lacks deterministic destruction. Implementing, for example, a data structure based on unmanaged memory in C# in such a way that it can be safely used by code outside the library without undermining the safety of the…

Maybe you should explore better Marshall Interop services and the span related improvements.

IDisposable is definitely an alternative when coupled with Roslyn analysis or SonarQube.

As if doing it in C++ doesn't require the same knowledge level, worse actually, as it also requires ISO C++ mastery and a good knowledge of how each compiler being used handle IB and UB.

Also unless static analysis is getting used, RAII can also get thr ownership wrong, specially with use after move errors, or smart pointers incorrectly given as arguments.

Re: Go does not need a Java-style GC

#154

Earlier quoted context omitted.

There's also ref which is almost like pointers and safe. Span/Memory do not remain an absolute last resort, they are becoming the standard way for string formatting/parsing/(de)serialization and IO.

I didn't say Span/Memory are a last resort, I said C style memory management (AllocHGlobal/Free), despite being somewhat improved by Span/Memory, remains an absolute last resort. Span/Memory aren't primarily aimed at handling unmanaged memory, though they're useful for it.

Of course C style memory management is a last resort, 99% of devs don't need it, and the 1% that actually need it, better learn to use V-Tune.

Re: Go does not need a Java-style GC

#155
post #127
post #63

Earlier quoted context omitted.

Additionally he doesn't seem to know that much about C#, which also has advanced GC, while allowing for C++ like memory management, if needed.

It's odd how most people that haven't used a VM with GC are amazed by Go (no VM) and WASM (no GC) but still fail to understand that with a GC _AND_ VM you can code something that doesn't crash even if you make a big mistake! And they haven't even bothered to try it out! To use anything other than JavaSE/C# on the server you really need very good arguments!

> To use anything other than JavaSE/C# on the server you really need very good arguments!

Haha! Quoting this so you can't delete it.

Re: Go does not need a Java-style GC

#156
post #153

Earlier quoted context omitted.

I do mean RAII, which is fundamental to C++. Memory management without it is not "C++ like". IDisposable is not a substitute for RAII, and C# has nothing that can manage ownership in equivalent ways as it lacks deterministic destruction. Implementing, for example, a data structure based on unmanaged memory in C# in such a way that it can be safely used by code outside the library without undermining the safety of the…

Maybe you should explore better Marshall Interop services and the span related improvements. IDisposable is definitely an alternative when coupled with Roslyn analysis or SonarQube. As if doing it in C++ doesn't require the same knowledge level, worse actually, as it also requires ISO C++ mastery and a good knowledge of how each compiler being used handle IB and UB. Also unless static analysis is getting used, RAII c…

I used Spans extensively. They help (mostly by providing efficient bounds checking), but not much. The main problem, as I mentioned initially, is the composability of this sort of code.

I wasn't trying to give some kind of defence of C++ here, just pointing out the dissimilarities to C#. This particular piece of code would have been far easier in C++ and RAII would have been a huge help, but the system as a whole would have been an utter nightmare in C++ (which I know because I've worked on multiple similar systems in C++).

Re: Go does not need a Java-style GC

#157
post #153

Earlier quoted context omitted.

Maybe you should explore better Marshall Interop services and the span related improvements. IDisposable is definitely an alternative when coupled with Roslyn analysis or SonarQube. As if doing it in C++ doesn't require the same knowledge level, worse actually, as it also requires ISO C++ mastery and a good knowledge of how each compiler being used handle IB and UB. Also unless static analysis is getting used, RAII c…

I used Spans extensively. They help (mostly by providing efficient bounds checking), but not much. The main problem, as I mentioned initially, is the composability of this sort of code. I wasn't trying to give some kind of defence of C++ here, just pointing out the dissimilarities to C#. This particular piece of code would have been far easier in C++ and RAII would have been a huge help, but the system as a whole wou…

Sure, but I am the opinion it does compose, if one embraces it isn't the same as writing C++ in C#, not trying to downplay your experience on the matter.

For example, here are the Roslyn analysers for a more RAII like experience with IDisposable,

https://github.com/DotNetAnalyzers/IDisposableAnalyzers

Turn "DISP004-Don't ignore created IDisposable." into a compiler error and you have your region allocated RAII like experience.

And moving a bit the goal posts, for those scenarios where C# fails completly to provide a usefull solution, we can rewrite just that module into C++ (preferably C++/CLI when only Windows matters), and have the best of both languages.

Re: Go does not need a Java-style GC

#158
post #6

> In a multithreaded program, a bump allocator requires locks. That kills their performance advantage. Java uses per-thread pointer bump allocators[1] > While Java does it as well, it doesn’t utilize this info to put objects on the stack. Correct, but it does scalar replacement[2] which puts them in registers instead > Why can Go run its GC concurrently and not Java? Because Go does not fix any pointers or move any o…

Scalar replacements (as currently implemented in Java) does not work in real-world programs. Well-written code does not need it. Poorly written code can not trigger it, because the JIT is too dumb and isn't getting better. There is no sane test to determine whether a piece of code will be inlined in Java. In practice anything more complex than byte array is unlikely to be inlined. Even built-in ByteBuffers aren't! Me…

Which JIT? There are plenty of them to choose from across Java implementations.

Re: Go does not need a Java-style GC

#159
post #27

Earlier quoted context omitted.

While I agree that the java gRPC lib is better maintained, I don’t agree with your second point. Java’s GCs are the state of the art, that can manage heap sizes up to 16 tera bytes. Other GC implementations would simply die there.

That’s neat, but a lot of applications will never need 16TB.

Well, you are talking about java applications...

Re: Go does not need a Java-style GC

#160
post #142

The author doesn't really understand how Java escape analysis works, and just focuses on one key aspect: "It does not replace a heap allocation with a stack allocation for objects that do not globally escape." The author then implies that escape analysis is only used to reduce lock acquisition. Java escape analysis will replace a heap allocation with a stack allocation if the code is fully inlined. This is known as s…

I don't know much about this, but upthread various people say that scalar replacement happens very rarely if at all, currently. E.g.: https://news.ycombinator.com/item?id=29324132 . Could you perhaps comment on that, since you seem to have experience?

First of all that blog post is wrong, it uses Optional which isn't a value type to start with, and contains internal fields.

It is considered a value like class, that will eventually be turned into a value type when Valhala arrives, until then there are no guarantees in scalar replacement.

Secondly, GraalVM or Azul are much better at it, which the author didn't bother to try their blog post on.

Post reply on HN