News for hackers. Stuff that matters.
Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by Skinney on Friday September 17, 2021 @07:44AM (#28564273)
Exactly zero pauses only exist if you never free memory, which for most purposes is not an option. In most languages, freeing all all the heap-allocated objects of a big array will take longer than in a language with GC. The reason pauses tend to be bigger in a GCed language is because all the freeing is being done at once, instead of every single time an object is determined to no longer be needed.

In any case, the tradeoff you're making is that you have deal with memory. Even in a language like Rust, you need to care about references, ownership, struct vs heap and possibly even reference counting. You might even be bitten by "running out of memory" due to memory defragmentation.

In most cases, you don't need to care about these things in a GC'ed language, at the expense of larger memory usage and possibly noticable pauses.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by zozbot234 on Friday September 17, 2021 @08:34AM (#28564697)
> In most cases, you don't need to care about these things in a GC'ed language, at the expense of larger memory usage and possibly noticable pauses.

GC has other drawbacks as well. The whole tracing workload (which still exists even in low-latency, concurrent GC's) messes up your locality of references and interacts badly with CPU- and OS-level caching and memory management. Plus the mutator part of your program is heavily constrained in how it can layout objects in memory, since the tracing GC must be enabled to select references to other objects unambiguously. It's a non-trivial drain on performance on memory-bandwidth limited workloads, which tends to be most of them these days.

Reference counting does away with most of these issues, and gives you deterministic finalization of all resources not just memory. Alternately, you can selectively use arenas to defer the freeing of some objects, while still being deterministic elsewhere.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by ncmncm on Friday September 17, 2021 @05:34PM (#28571165)
zozbot has it right.

Reference counting is a form of GC to use when performance doesn't matter. Performance never matters except where it does. But automated memory management without reference counting is usual practice in a modern non-GC language.

Freeing an array of objects only involves a series of calls to a deallocator when the array elements have pointers in them. That is typically unavoidable in Java, but not in non-GC languages.

Arena allocation, where memory in a subsystem is allocated using a specific allocator object, deallocation there is an in-line no-op, and all of subsystem memory is reclaimed en bloc at a chosen event boundary, is a common alternative where more control is needed. It is still not "manual memory management"; memory for objects is managed invisibly, and still without reference counting.

The usual advertising for GC is that it means you don't need to think about managing memory. The actual experience is that, where it matters at all, you have to think about it a great deal more.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by nyanpasu64 on Friday September 17, 2021 @10:06AM (#28565626)
I can write (and am in fact developing right now) a music app in a non-GC language, with a real-time audio thread which (unless faced with unusual inputs like hundreds of simultaneous events) performs zero allocations or deallocations after initial startup. It acquires and releases all heap allocations from a wait-free queue between the audio thread and GUI thread.

If I were to port the app to C#, I have no way of telling the C# GC to never pause the audio thread, and to only pause the GUI thread. I'm not sure if it's possible for a tracing GC to coexist with a never-paused thread which owns manually memory-managed types, and for the two threads to exchange manually freed or GC'd objects without FFI boilerplate, serialization, or copying. If it exists (and there's a GUI framework written in the GC portion of the language), let me know!

Admittedly manual memory management does mean a lot more things to worry about (ranging from manual memory management to lock-free wait-free programming) Personally I find deterministic lifetimes and single ownership which can be moved/swapped to be elegant. However, Qt's QObject system combines the practical disadvantages of manual freeing (having to track complex semantics in your head, and check whether each method call transfers ownership or not, with leaks or use-after-free if you get it wrong) with the inelegance of GC (pervasive aliasing and mutability, unclear ownership, a magical runtime-like system).

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by Skinney on Friday September 17, 2021 @10:39AM (#28565992)
Sure, and in your specific use case, the tradeoff of dealing with memory seems worth it.

My point was that there are tradeoffs, which you admit. The comment i responded to indicated that there wasn’t one.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by kaba0 on Friday September 17, 2021 @01:42PM (#28568474)
I agree that your specific use-case is indeed good reason for manually managed memory, but theoretically, I don’t see anything inherent in specifying GC on a per-thread basis. Like, perhaps one could set a property on a new Thread object and set GC to false - that would probably allow your program to function even in a managed environment.
Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by ncmncm on Friday September 17, 2021 @04:43PM (#28570700)
Not using GC does not, in fact, imply "manually managed memory". Manually managed memory is the only thing possible in C, but C is not the only non-GC language. The most commonly used non-GC languages provide other mechanisms, and usual practice in them is to rely on their non-GC, automated memory management.
Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by kaba0 on Saturday September 18, 2021 @03:44AM (#28574442)
Do you mean RAII and rust’s ownership model? It still has very similar tradeoffs to manual memory management, they are just much less error prone.

But the fundamental thing is that you still have to think about memory, memory layout will have to be considered during refactors, etc.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by ncmncm on Sunday September 19, 2021 @04:45AM (#28582750)
If you are not thinking about memory, or memory layout, you are not programming. Anyway, not programming well.

And "tradeoffs" is a misleading term to apply to a process that does not involve giving up anything in exchange for the benefit of pause-free, fully predictable operation.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by kaba0 on Sunday September 19, 2021 @05:26AM (#28582917)
There are different levels of “thinking about memory”. The distinction between low and high level languages is not arbitrary. In a CRUD app, you don’t want memory layout to be the center of attention, a major refactor in abstraction should not really require a re-thought on the life time of objects, etc.

And you do absolutely give up something with not using a GC: speed of development, much bigger teams can work on the project at the same time while not stepping as much on each other’s foot, etc. It’s not an accident that perhaps the majority of all software development is in managed languages, where it is not absolutely crucial to control the exact memory layout.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by ncmncm on Sunday September 19, 2021 @09:52PM (#28589673)
> "you do absolutely give up ... speed of development"

That is the advertising claim, not substantiated.

A more plausible explanation for "the majority ... in managed languages" is: it enables employing lower-skilled, thus more easily obtained, labor. It doesn't so much matter how fast development is. Such practices commonly split a simple job among five or more people (a "team") who, collectively, probably cost more than one more-skilled employee who could do it all in much less time, but who is hard to attract to do it at all, and anyway better used elsewhere.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by Skinney on Monday September 20, 2021 @02:09AM (#28590769)
I used to work in a C/C++ embedded shop, and I work now at a place where only GCed languages are used.

The statement about enabling lower-skilled employers to be hired is pretty much false. Embedded development payed significantly less than most places that uses Java today (at least in Norway), and there's really no difference in the skill of the people I work with.

There's a _significant_ difference in the problem being solved though. The project I'm working at now is, code-wise, bigger by an order of magnitude. As is the problem domain (ticket-selling services, vs firmware of payment terminal in old job).

When doing embedded, I never had to care about racing conditions in threads or across several microservices. The embedded device was single-core anyways, and only talked to one server.

Dealing with memory has been replaced by handling concurrency. Of those I'd argue that the latter is significantly harder than the first. But both add to development time, as it becomes a core point in most design discussions.

In our case, we truly do not need to care about memory. If we run out of it, we either upgrade the instance or add another instance. The monthly hardware cost is lower than the hourly cost of a developer, anyways. Having one less thing to worry about decreases developer time, as there's one less thing to include in our designs, and one less thing to worry about going wrong.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by kaba0 on Monday September 20, 2021 @01:59AM (#28590734)
If it were 50-50 or so, I would be open to this explanation. But it is an overwhelming majority, making the claim not only substantiated, but empirically proved.

And frankly, you are not getting ahead with your arbitrary gatekeeping on “who is a real programmer”.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by Skinney on Saturday September 18, 2021 @03:53AM (#28574476)
Erlang is a good example of a per “thread” GC (erlangs unit of concurrency is the process). When one GC triggers, it doesn’t pause the rest of the program.

Not sure if you can disable the GC entirely, but you can set the initial heap high enough that it won’t trigger for the lifetime of the process.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by saagarjha on Friday September 17, 2021 @08:28AM (#28564653)
Of course, certain applications do indeed never allocate once they have started up.
Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by ncmncm on Sunday September 19, 2021 @09:55PM (#28589685)
Indeed, that is a very common practice, where latency matters. You might have a great deal of memory heap activity in the first second, and then hardly any for months after.
Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by yakubin on Friday September 17, 2021 @09:33AM (#28565287)
> In most languages, freeing all all the heap-allocated objects of a big array will take longer than in a language with GC.

Only if elements of the array are separately allocated (boxed) or have destructors.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by Skinney on Saturday September 18, 2021 @03:49AM (#28574465)
And if the array is heap allocated.
Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by yakubin on Saturday September 18, 2021 @05:46AM (#28574925)
If the array is stack-allocated and the elements are boxed (i.e. heap-allocated) or have destructors, you are still going to need to call the destructors or the free on the elements when the array goes out of scope.
Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by ncmncm on Sunday September 19, 2021 @03:55PM (#28587373)
Such a layout, and all it costs, is typically unavoidable in GC languages, and usually easily avoided in non-GC languages, particularly in cases where it would matter.

Thus, it is incorrect to talk about multiple calls to a deallocator. You get just one for the whole array.

Re:Shenandoah in OpenJDK 17: Sub-millisecond GC pauses by Skinney on Monday September 20, 2021 @02:11AM (#28590776)
My point was: it still takes longer time to de-allocate a large array even if the only thing that needs to be freed is the array itself, when compared to a GC. GC never needs to free anything, it instead overwrites garbage memory with live memory.