See also Raymond Chen: https://devblogs.microsoft.com/oldnewthing/20180228-00/?p=98... - who quotes the story of a piece of embedded software which accepted leaking since it would be used in the runtime of a missile.
Epsilon: The JDK’s Do-Nothing Garbage Collector
31–40 of 77 posts
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#32See also Raymond Chen: https://devblogs.microsoft.com/oldnewthing/20180228-00/?p=98... - who quotes the story of a piece of embedded software which accepted leaking since it would be used in the runtime of a missile.
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#33Earlier quoted context omitted.
I think the concern is those resources might be external and not cleaning up correctly leaves them in an inconsistent state. Not saying this is best practice but I've seen it done.
Finalisers are not guaranteed to be called by GC in theory, and in practice they run asynchronously even if they are going to be called, so aren't likely to be called if you GC and then exit. So how does calling GC help with anything?
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#34Earlier quoted context omitted.
Hence my question.
I still don't understand your question, sorry: > can't the regular GCs just not clean up on program exit Why do you need to clean up your memory - at all, GC or otherwise - on program exit? The process and all its resources will be gone.
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#35Now I'm no Java expert, far from it, so would appreciate any answers to this. I'm interacting with bunch of CLIs that are either in Java or using the JVM otherwise (Clojure mostly), how much of the startup time for this things can be attributed to the GC? It's mentioned in the article that short-running programs (almost all CLIs I use) could use Epsilon since the heap is cleared on exit anyways. But wondering how muc…
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#36Now I'm no Java expert, far from it, so would appreciate any answers to this. I'm interacting with bunch of CLIs that are either in Java or using the JVM otherwise (Clojure mostly), how much of the startup time for this things can be attributed to the GC? It's mentioned in the article that short-running programs (almost all CLIs I use) could use Epsilon since the heap is cleared on exit anyways. But wondering how muc…
I think the overhead of GC is negligible for many small programs. Claes Redestad @ Oracle gives a good overview here. https://cl4es.github.io/2019/11/20/OpenJDK-Startup-Update.ht... I would look into GraalVM native images if you want fast startup.
In modern GCs, allocation is already as fast as can be (pointer-bump allocation), so I imagine the only win in chopping out the GC is that you don't need to initialize the GC (it's otherwise roughly equivalent to simply terminating before the GC needs to be invoked).
Perhaps the DMD example isn't quite the same, though, as it's possible its GC has slower allocation than pointer-bump.
[0] https://www.drdobbs.com/cpp/increasing-compiler-speed-by-ove...
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#37Earlier quoted context omitted.
I still don't understand your question, sorry: > can't the regular GCs just not clean up on program exit Why do you need to clean up your memory - at all, GC or otherwise - on program exit? The process and all its resources will be gone.
But regular GCs DO run at the end of the program, so my question was, why don't they just skip the final cleanup.
Which GCs do that? I'm not aware of any.
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#38Earlier quoted context omitted.
I still don't understand your question, sorry: > can't the regular GCs just not clean up on program exit Why do you need to clean up your memory - at all, GC or otherwise - on program exit? The process and all its resources will be gone.
But regular GCs DO run at the end of the program, so my question was, why don't they just skip the final cleanup.
If the platform doesn't feature finalizers, or if it is known that they've not been used, there'd be no point at all.
Re: Epsilon: The JDK’s Do-Nothing Garbage Collector
#39To address the short-running program issue, can't the regular GCs just not clean up on program exit?
When I was writing the Epsilon JEP, I meant that it might be futile to have a hundreds-of-ms-long GC cycle, when the program exits very soon anyway, and the heap would be abandoned wholesale. The important bit of trivia is that GC might be invoked long before 'the whole memory' is exhausted. There are several reasons to do this: learning the application profile to size up generations or collection triggers, minimizing the startup footprint, etc. GC cycle then can be seen as the upfront cost that pays off in future. With the extremely short-lived job that future never comes.
Contrived example:
$ cat AL.java
import java.util.*;
public class AL {
public static void main(String... args) throws Throwable {
List l = new ArrayList();
for (int c = 0; c
Ooof, 12.5 seconds to run, and about 2 cpu-minutes taken with Parallel: $ time jdk11.0.5/bin/java -XX:+UnlockExperimentalVMOptions -Xms3g -Xmx3g -XX:+UseParallelGC -Xlog:gc AL
[0.015s][info][gc] Using Parallel
[0.988s][info][gc] GC(0) Pause Young (Allocation Failure) 768M->469M(2944M) 550.699ms
...
[12.281s][info][gc] GC(3) Pause Full (Ergonomics) 1795M->1615M(2944M) 7660.045ms
100000000
real 0m12.464s
user 1m53.618s
sys 0m1.087s
Much better with G1, but we still took 11 cycles that accrued enough pauses to affect the end-to-end timing. Plus GC threads took some of our precious CPU. $ time jdk11.0.5/bin/java -XX:+UnlockExperimentalVMOptions -Xms3g -Xmx3g -XX:+UseG1GC -Xlog:gc AL
[0.031s][info][gc] Using G1
[0.452s][info][gc] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 316M->314M(3072M) 124.119ms
...
[2.518s][info][gc] GC(11) Pause Young (Normal) (G1 Evacuation Pause) 2321M->2324M(3072M) 79.496ms
100000000
real 0m2.953s
user 0m16.880s
sys 0m0.872s
Now Epsilon, whoosh, 1.5s end-to-end, and less than 1s of user time, which is probably the only running Java thread itself, plus some OS memory management on allocation path. $ time jdk11.0.5/bin/java -XX:+UnlockExperimentalVMOptions -Xms3g -Xmx3g -XX:+UseEpsilonGC -Xlog:gc AL
[0.004s][info][gc] Using Epsilon
...
[1.387s][info][gc] Heap: 3072M reserved, 3072M (100.00%) committed, 2731M (88.93%) used
real 0m1.480s
user 0m0.830s
sys 0m0.699s
You might think fully concurrent GCs would solve this, and they partially do, by avoiding large pauses. But they still eat CPUs. For example, while Shenandoah is close to Epsilon in doing the whole thing in about 1.7s wall clock time, it still takes quite significant CPU time. Therefore, that benefit is there because machine has spare CPUs to offload that work to. $ time jdk11-shenandoah/bin/java -XX:+UnlockExperimentalVMOptions -Xms3g -Xmx3g -XX:+UseShenandoahGC -Xlog:gc AL
[0.009s][info][gc] Using Shenandoah
...
[0.913s][info][gc] Trigger: Learning 3 of 5. Free (1651M) is below initial threshold (2150M)
[0.913s][info][gc] GC(2) Concurrent reset 1265M->1267M(3072M) 0.689ms
[0.914s][info][gc] GC(2) Pause Init Mark 0.111ms
[1.276s][info][gc] GC(2) Concurrent marking 1267M->1925M(3072M) 361.985ms
[1.306s][info][gc] GC(2) Pause Final Mark 0.465ms
[1.306s][info][gc] GC(2) Concurrent cleanup 1924M->1748M(3072M) 0.171ms
real 0m1.761s
user 0m5.688s
sys 0m0.633sRe: Epsilon: The JDK’s Do-Nothing Garbage Collector
#40Earlier quoted context omitted.
Finalisers are not guaranteed to be called by GC in theory, and in practice they run asynchronously even if they are going to be called, so aren't likely to be called if you GC and then exit. So how does calling GC help with anything?
I agree with you and how it's not reliable. I just remember the Rust community going through this same kerfuffle with their Drop trait not being guaranteed not too long ago.