[HN Gopher] JDK 20 G1/Parallel/Serial GC Changes
       ___________________________________________________________________
        
       JDK 20 G1/Parallel/Serial GC Changes
        
       Author : carimura
       Score  : 151 points
       Date   : 2023-03-17 13:20 UTC (9 hours ago)
        
 (HTM) web link (tschatzl.github.io)
 (TXT) w3m dump (tschatzl.github.io)
        
       | twic wrote:
       | > thread-local allocation buffers (PLABs)
       | 
       | :-/
        
         | froh wrote:
         | mind to expand?
        
           | agilob wrote:
           | PLAB is promotion-local allocation buffer.
           | 
           | TLAB is thread-local allocation buffer.
           | 
           | I think there's just a tpyo in the post.
           | 
           | During GC phases, threads can use PLABs to reduce need for
           | synchronisation while scanning TLABs.
        
       | ordx wrote:
       | Is there a good decision flowchart on how to chose GC for a
       | particular task/application?
        
         | vips7L wrote:
         | Oracle has an overview here [0]. But in general I would say
         | unless you're facing an issue just to let the JVM pick the GC
         | and only really tune -Xmx
         | 
         | [0]
         | https://docs.oracle.com/en/java/javase/18/gctuning/introduct...
        
           | colechristensen wrote:
           | Yup, every once in a while use the various available tools to
           | watch your memory usage patterns and how GC runs. If it looks
           | fine continue to leave it as is.
        
         | [deleted]
        
         | the8472 wrote:
         | you haven't encountered any problem: stick to the default
         | 
         | single-core, latency doesn't matter, low footprint: serial
         | 
         | throughput: parallel or G1
         | 
         | balance between latency, footprint and throughput: G1
         | 
         | latency more important than throughput or footprint: ZGC or
         | shenandoah
         | 
         | missiles and HFT: Epsilon
        
         | exabrial wrote:
         | Always start with the question, do you need to optimize? :)
         | Most likely, Probably not! Java is _fast_, and the JVM is
         | pretty good at what it does; 95% of the time merely checking
         | for GC thrashing is all that's needed.
         | 
         | Otherwise, start with G1 and get your Xmx value in the
         | ballpark. VisualVm can help you determine if you're thrashing.
         | Are you GCing like 10+ times per second? Keep an eye on it. If
         | you start hitting giant pause times and 50+ collections a
         | second, you've got problems :) Increase Xmx. (and no, please
         | don't set Xms = Xmx).
         | 
         | If you have issues past that, it's not the garbage collector
         | that needs help; the next step is to audit your code base. Bad
         | code makes any Garage Collector in any language to misbehave.
         | 
         | For instance, are you `select *`ing from a table then using the
         | Java streams api to filter rows back from a database? That will
         | cause GC issues :) fix that first.
         | 
         | So now if you've got to this point and you still need to
         | optimize, what we've done is just run through the different
         | collectors under load. One of our JVMs is a message broker
         | (ActiveMQ 5.16.x) and we push a couple thousand messages per
         | second through it. We found that Shenandoah actually improved
         | latency for our particular use case, which was more important
         | that throughput and outright performance.
         | 
         | Oh, and if your application and usecase is _extremely_
         | sensitive to latency, forget everything I wrote and contact
         | Azul systems about their Prime collector. They're pretty
         | awesome folks.
        
           | [deleted]
        
           | Szpadel wrote:
           | do you mind explaining to someone that does not do any java
           | dev, but operates some java servers (like elasticsearch, etc)
           | what's wrong with Xms = Xmx?
           | 
           | And what is better strategy to set it?
        
             | exabrial wrote:
             | where to start... first the other commenter is correct. If
             | you need to run to the connivence store that's 250 yards
             | away, what is more efficient? Firing up a 7,100hp Union
             | Pacific Diesel locomotive and plowing through
             | everything/everyone to get there, or taking a electric
             | scooter? A smaller heap means less to scan, meaning less
             | work, meaning lower latency. Now G1GC removes some of this
             | penalty due to its algorithm, but in general, less memory
             | is less memory scanned, meaning better best-case
             | performance from a GC. Let that Adaptive GC Boundary do
             | it's thing.
             | 
             | and now, rant time: well, Xms allegedly improves start
             | times. Is that really important? No. Is that really true
             | anyway? Not really. Xms hides problems... Yes. Give that
             | memory to the OS. Let it fill it up with things like disk
             | cache or COW artifacts. Xms is an attempt to help people
             | that aren't planning properly or testing. Yes. Instead,
             | Test your systems under full load with Xms off and adjust,
             | measure, experiment, repeat.
             | 
             | Elastic is sort of a special case because it's a
             | 'database', but, I'd rather know the minimum Xmx my system
             | actually needs by experimentation, and you can't find that
             | with Xms enabled. And even then, I don't see MySQL
             | allocating 100% of its InnoDb bufferpools at startup.... :)
        
               | zht wrote:
               | honestly none of these sound like compelling reasons to
               | not just set -Xms to Xmx
        
               | lkorinth wrote:
               | You scan the live set (which most often is not dependent
               | on the heap size). Bigger heap most often means better
               | performance. Setting Xms to Xmx is good and valid if you
               | know how much memory you need (which often is the case).
               | If you prefer high throughput, then relax the pause-time
               | goal by using -XX:MaxGCPauseMillis or provide a larger
               | heap. If latency is the main requirement, then modify the
               | pause-time target. Avoid limiting the young generation
               | size to particular values by using options like -Xmn,
               | -XX:NewRatio and others because the young generation size
               | is the main means for G1 to allow it to meet the pause-
               | time. Setting the young generation size to a single value
               | overrides and practically disables pause-time control.
               | [1]            Setting -Xms and -Xmx to the same value
               | increases predictability by removing the most important
               | sizing decision from the virtual machine. However, the
               | virtual machine is then unable to compensate if you make
               | a poor choice. [1]
               | 
               | [1] https://docs.oracle.com/en/java/javase/19/gctuning/in
               | troduct...
        
               | exabrial wrote:
               | > However, the virtual machine is then unable to
               | compensate if you make a poor choice.
               | 
               | > Test your systems under full load with Xms off and
               | adjust, measure, experiment, repeat.
               | 
               | precisely what I'm saying.
        
               | mikmoila wrote:
               | >>You scan the live set (which most often is not
               | dependent on the heap size).
               | 
               | This was an eye-opener for me; That GCs performance do
               | not depend on the size of garbage but on the size of the
               | live objects, finalizers excluded.
        
             | agilob wrote:
             | If you run it in a container the best advice it to leave
             | things with default options. JVM has ergonomic GC options
             | and with adaptive heap sizing. 95% of time you dont need to
             | change anything at all.
        
             | natdempk wrote:
             | This Stack Overflow answer is pretty decent:
             | https://stackoverflow.com/a/23284897
             | 
             | I think basically the argument is that by setting the min
             | bound lower, you allow the JVM to shrink the heap. This
             | could maybe be beneficial towards reducing pause time
             | because the JVM has less memory to manage overall. That
             | being said, that SO answer also mentions:
             | 
             | > Sometimes this behavior doesn't give you the performance
             | benefits you'd expect and in those cases it's best to set
             | mx == ms.
             | 
             | I've also seen apps configured this way professionally for
             | similar reasons. You might imagine some app that leads to
             | the JVM pathologically trimming the heap in a way that
             | isn't desirable and thus impacts performance in some subtle
             | way, etc. The answer with a lot of this stuff is usually
             | try both ways, measure, see if you can observe a meaningful
             | difference for your apps/workload for typical/peak traffic.
             | 
             | Background: I've worked on Java apps for a few years at
             | reasonable scale and worked on GC pressure issues in that
             | time.
        
         | brucethemoose2 wrote:
         | I think generational ZGC is going to be the "sane default"
         | soon.
        
           | popfalushi wrote:
           | Default gc depends on how many cpus and ram vm has. With 1
           | core it is always serialgc, for example. 2 cores and less
           | than 4 gb - concurrent mark and sweep IIRC. G1GC starts a bit
           | later.
        
             | brucethemoose2 wrote:
             | Yeah but you dont necessarily want to use those defaults.
             | They strike me as kind of archaic.
             | 
             | For low resource use cases, you probably want Graal AOT
             | above all else... which means G1GC or serial, I think.
        
               | agilob wrote:
               | GraalAOT, do you mean native image or C2 compiler?
               | Neither of these tuning is applicable in a discussion
               | about GCs
        
             | agilob wrote:
             | This is so wrong:
             | 
             | >With 1 core it is always serialgc
             | 
             | Even with 1 CPU ParallelGC has lower latencies than
             | SerialGC on 1 CPU. SerialGC will be better on environment
             | with limitations on number of threads, not number of CPUs.
             | 
             | > 2 cores and less than 4 gb - concurrent mark and sweep
             | IIRC
             | 
             | CMS has been deprecated in 11 and removed later in a non-
             | LTS release. JVM ergonomic will automatically turn on
             | >G1GC< when it detects JVM has at least 2 CPUs and 1792Mb
             | of RAM (not heap, memory in total). When either or both
             | numbers are lower then ParallelGC is enabled automatically.
        
             | lkorinth wrote:
             | CMS was removed in 14.
        
           | re-thc wrote:
           | Would be good to have more benchmarks and articles on G1 vs
           | ZGC once that happens.
        
           | marginalia_nu wrote:
           | Eh, there's probably always going to be a different answer
           | depending on whether you prioritize latency vs throughput.
        
       | yupyup54133 wrote:
       | Love Java. Very much looking forward to LTS Java 21. <3
        
         | ithrow wrote:
         | In the world of web development why would one pick Java(or
         | Kotlin) over TS/node.js ?
        
           | boomskats wrote:
           | Java's superior G1/Parallel/Serial GC that they're changing?
        
           | the8472 wrote:
           | It can execute application code on more than one thread at a
           | time. Something I'd think people would appreciate in the age
           | of many-core systems.
        
           | cbm-vic-20 wrote:
           | Java has really good runtime monitoring capability. Being
           | able to get a thread dump from a production system, or
           | generating Flight Recorder logs for offline analysis is
           | incredibly useful. Is there something similar in the Node
           | ecosystem?
        
             | winrid wrote:
             | Nope. You can get a heap dump which gives you object
             | allocation stats by "object shape" which is incredibly less
             | useful than stats by ClassPath.
        
           | pphysch wrote:
           | I'd wager TS/node/etc going the way of PHP and JQuery in the
           | next decade. SPA will go full WASM (which you could
           | technically use Java for) and non-SPA will be built off
           | better browsers (e.g. WebKit adding nested CSS) and HTMX-
           | style solutions. Note that it doesn't mean everyone will be
           | rolling their own WASM-based engine, but that there will be a
           | bunch of public WASM-based engines (like PyScript/Pyodide
           | stuff) that are tailored for specific domains than one-size-
           | fits-all React.
           | 
           | This leaves "full stack JS" in an awkward middle ground.
           | Sure, you could still use it on your backend (like PHP), but
           | why?
           | 
           | We use JS because there were literally no other practical
           | options, but better browsers and WASM are providing new
           | options.
        
           | 62951413 wrote:
           | For the same reasons you'd pick golang over python/TS.
           | 
           | Only you'll get higher-level abstractions (pattern matching,
           | FP-style maps/flatMaps&Co throughout the standard library)
           | and powerful collections with full support for generics.
           | 
           | Better yet, start with Kotlin from day one.
        
             | alfalfasprout wrote:
             | At that point, why not Scala?
        
               | dxxvi wrote:
               | Agreed. If somebody doesn't know Java and decides to jump
               | to Kotlin, I will have the same question: why not Scala
               | which is used more than Kotlin on computers (i.e. non-
               | Android)?
        
       | fulafel wrote:
       | Has anyone ever tried to port OpenJDK's fancy garbage collectors
       | other runtimes? I guess often GCs are quite intimately tied to
       | other details of the runtime and specialized to code patterns and
       | use cases of particular languages, but still, would be
       | interesting to hear about attempts.
        
         | mike_hearn wrote:
         | That would be difficult. The GCs share a lot of code, and have
         | a lot of code to deal with Java specific things like class
         | unloading and soft/weak/phantom references. It's easier to run
         | other languages on top of the JVM runtime, which is what
         | projects like Truffle and JRuby do.
        
         | lemming wrote:
         | I've wondered how feasible this would be. In general, I think
         | the other commenters are correct that GCs tend to be intimately
         | tied to the runtimes. But the JVM now has an interface for
         | garbage collection (https://openjdk.org/jeps/304), which might
         | make the GCs easier to extract and use in other projects. I'm
         | not aware of anyone trying though.
        
         | titzer wrote:
         | AFAIK, no. The opposite is true with MMtk
         | (https://www.mmtk.io), which is a toolkit with many GC
         | algorithms implemented that has been plugged into other
         | runtimes, including, as it happens, OpenJDK.
        
         | throwaway894345 wrote:
         | > I guess often GCs are quite intimately tied to other details
         | of the runtime and specialized to code patterns and use cases
         | of particular languages
         | 
         | This is why I don't understand the WASM GC proposal, which I
         | understand to be an attempt to make a GC that works for all
         | languages. Can you really write a GC that _performantly_
         | supports both Java and Go given the different tradeoffs
         | /approaches each makes with respect to memory management,
         | layout semantics, etc?
        
           | fulafel wrote:
           | I agree somewhat. But still JVM GC works ok for several other
           | languages (Clojure, JRuby, Scala, Kotlin etc).
        
             | throwaway894345 wrote:
             | Sure, but all of those languages "look like Java" from a
             | memory management perspective. Namely, programs written in
             | those languages idiomatically assume that allocations are
             | dirt cheap (bump allocator) and thus they allocate _a lot_
             | of garbage. A language like Go tends to assume allocations
             | are more expensive (tradeoff for a simple /non-moving, low
             | latency GC) and consequently makes fewer, larger
             | allocations. It's not obvious to me that a single GC can
             | support both extremes performantly.
        
           | entropicdrifter wrote:
           | >Can you really write a GC that performantly supports both
           | Java and Go given the different tradeoffs/approaches each
           | makes with respect to memory management, layout semantics,
           | etc?
           | 
           | I mean, the Graal JVM GC supports a ton of languages,
           | especially if you include their LLVM support. Many of them
           | are quite high performance. Truffle Ruby I believe is still
           | (one of if not) the fastest Ruby implementation(s).
        
             | throwaway894345 wrote:
             | Sure, but are the languages that Graal supports diverse
             | from the perspective of the assumptions they make? E.g.,
             | it's not surprising to me that any JVM GC would work for
             | Java, Ruby, Python, etc since all of these languages
             | idiomatically allocate lots of garbage like allocations are
             | cheap (they all "look like Java" from a memory management
             | perspective). On the other hand, Go assumes allocations are
             | expensive and it tends to make fewer, larger allocations
             | (the tradeoff is that it can have a relatively simple, low
             | latency GC). It's not clear to me that a single general
             | purpose GC (i.e., it's performant for all cases, not just
             | the things-that-look-like-Java case) can exist, but I'm
             | also not a GC expert.
        
               | mike_hearn wrote:
               | Go doesn't differ that much from other GC languages. GC
               | cost/complexity doesn't really change much with average
               | allocation size. Go putting less load on the GC just
               | means the JVM GCs would be playing on 'easy mode'.
        
       | throw0101b wrote:
       | Do people follow GC research at all 'for fun'? Any
       | places/sites/people to pay attention to for the latest and
       | greatest goings-on that may show up in production _x_ years from
       | now?
        
         | mike_hearn wrote:
         | Sure, I follow it but HotSpot is state-of-the-art, so if you
         | follow that team then you're basically following GC research
         | already. There's a little to be found in academia, but only
         | rarely these days. The implementation cost to get to the
         | cutting edge is too high.
        
         | BenoitP wrote:
         | I do follow Loom 'for fun', lurking the mailing list archives
         | [1]. You can definitely do the same for GC implementation [2]
         | (general topic list here [3]); but it may not talk a lot about
         | external initiatives like Shenandoah.
         | 
         | Beware that you're gonna have to filter a lot! There's patch
         | merging and very low detail implementation conversations. For
         | example, you'd be pleased to know that G1 can now skip a guard
         | in card-table clearing [4]. Don't ask me what is the card table
         | and guards and why do you need to clear it, though.
         | 
         | One thing I'm looking for in GC advances is new hardware
         | support for it in RISC-V J extension. There's gonna be memory
         | tagging (helping security and memory management in GCs), and
         | pointer masking (hardware support for what ZGC does under the
         | hood)[5]. But we're probably a good 5 years away from seeing
         | that in real life, if ever.
         | 
         | [1] https://mail.openjdk.org/pipermail/loom-dev/
         | 
         | [2] https://mail.openjdk.org/pipermail/hotspot-gc-dev/
         | 
         | [3] https://mail.openjdk.org/mailman/listinfo
         | 
         | [4] https://mail.openjdk.org/pipermail/hotspot-gc-
         | dev/2023-March...
         | 
         | [5] https://github.com/riscv/riscv-j-
         | extension/blob/master/point...
        
         | suresk wrote:
         | I am interested in this area too, but I don't know of any
         | single place to follow it all. I have found that there isn't an
         | avalanche of "new" stuff, but a lot of different ideas with
         | different tradeoffs that change in relevance based on usage
         | patterns, languages/runtimes, and hardware characteristics.
         | 
         | Besides the JVM resources linked by others, I found Richard
         | Jones's "Garbage Collection Handbook" to be a decent
         | introduction for background [1]. The Go team has written a
         | bunch about their GC approach [2] - it is really interesting to
         | see how it compares to the various options in the JVM and under
         | which scenario you might prefer one or the other. And
         | occasionally there are interesting articles on arxiv.
         | 
         | 1. http://gchandbook.org/
         | 
         | 2. https://go.dev/doc/gc-guide
        
         | carimura wrote:
         | We try and aggregate content from the GC team here [1].
         | 
         | [1] https://inside.java/tag/gc
        
       | gigatexal wrote:
       | Off-topic but about Java generally:
       | 
       | Java is such a storied and long-running and used-almost-
       | everywhere language especially in Data Engineering (see all the
       | Apache Data Eng projects like Calcite, Hudi, etc) but I just find
       | it soooooo verbose and everything being a class and having to
       | override things ugh .. it's all the things I hate about OOP in
       | the forefront.
        
         | carimura wrote:
         | One of the goals of Project Amber [1][2] is to move the
         | language towards a more data-oriented programming model. With
         | Records, patterns, sealed classes, etc., it should feel much
         | less verbose over time. And unrelated to your concern but
         | addressing some of the learning overhead, see Paving the
         | Onramp. [3]
         | 
         | [1] https://openjdk.org/projects/amber/
         | 
         | [2] https://inside.java/tag/amber
         | 
         | [3] https://openjdk.org/projects/amber/design-notes/on-ramp
        
           | halfmatthalfcat wrote:
           | So...Scala?
        
             | carimura wrote:
             | Sure, but you could refer to the lineage of a dozen
             | languages. Most of the world runs Java and evolving it
             | takes care and consideration not to alienate a massive user
             | base and ensuring that it evolves in the right way, not
             | quick responses to fashions and trends.
        
               | eternalban wrote:
               | Isn't there natural interop between Java and Scala? Why
               | needlessly enlarge the language.
        
               | vips7L wrote:
               | Scala is super complex, introduces breaking changes all
               | the time, is super slow to compile, multi-language
               | projects are also complex, and the decisions that are
               | right for Scala may not be right for Java.
        
               | oweiler wrote:
               | Scala is also on the way out, adoption is steadily
               | decreasing.
        
               | halfmatthalfcat wrote:
               | I'm not sure I would characterize it as "steadily". I
               | think it's leveled off but I would agree it's not
               | _gaining_ any market share currently.
        
               | ebruchez wrote:
               | The "super complex" and "introduces breaking changes all
               | the time" comments are unsubstantiated FUD. Scala has
               | evolved a lot in the last few years, particularly in the
               | area of binary compatibility. It's a wonderful language
               | and I can only recommend others try it. This from a
               | programmer very happy with Scala.
        
               | vips7L wrote:
               | And this is from a programmer that is not happy with
               | Scala. Every single time I've upgraded the compiler there
               | is a breaking change. They don't strictly follow semver.
               | Most recently upgrading from the 2.11 to 2.13 compiler
               | they made breaking serial version uid changes (I know
               | don't use java serialization, but that wasn't my
               | decision) and none of it was noted in the release notes.
               | 
               | When it comes to super complex just look at any of the
               | type signatures of the standard library for collections:
               | def ++[B >: A, That](that:
               | GenTraversableOnce[B])(implicit bf:
               | CanBuildFrom[IndexedSeq[A], B, That]): That
               | 
               | Comparing this to Java it is "super complex". IntelliJ
               | can't even figure out the types sometimes.
        
               | suresk wrote:
               | And then when a dependency of one of your dependencies is
               | broken agains the latest version. I know some of this has
               | been cleaned up, but it is one of the main reasons I no
               | longer use Scala - I have a rule about how long I'm
               | willing to spend on build issues vs actually writing
               | code, and Scala was always on the wrong side of that.
               | 
               | re: Complexity - At least the signatures for the core
               | collections have been cleaned up a fair amount. That
               | said, the richness of the type system and the prevalence
               | of operator overloading always made it feel like a
               | language you could be really productive in once you knew
               | the language and the current codebase really well, but
               | was really hard to just read through unfamiliar code and
               | know what is going on.
        
               | bcrosby95 wrote:
               | I wish Scala leaned into being a Haskell-like
               | (opinionated statically typed functional language) for
               | the JVM rather than a kitchen sink.
        
               | suresk wrote:
               | There was definitely a large and vocal part of the
               | community that wanted that, but I think early on there
               | was a lot of tension between Scala being "better Java"
               | and "Haskell for the JVM", and that probably hindered a
               | lot of adoption.
        
               | halfmatthalfcat wrote:
               | Yes, and you can (via SBT) slowly introduce Scala into an
               | existing Java codebase quite easily.
        
               | vips7L wrote:
               | I wouldn't wish SBT on my worst enemies.
        
               | dxxvi wrote:
               | A java project never uses sbt. Both maven and gradle have
               | plugins for Scala.
        
               | therealdrag0 wrote:
               | It's terrible. But at least I rarely have to touch the
               | config. I guess the silver lining is it's so bad we don't
               | use it for anything besides dependency management so
               | configs are simple and just copy pasted between projects
               | and rarely touched.
        
               | halfmatthalfcat wrote:
               | Surely with GPT, it can't be that bad anymore ;p
        
               | vips7L wrote:
               | We just updated our version and sometimes it'll get stuck
               | in an infinite compile recursion loop. I dream of maven.
        
               | snuxoll wrote:
               | Sure, but what about when you want to pull a Kotlin
               | library into a Scala application? It works, but usually
               | only works well if the library author limited themselves
               | to the subset of the language that interops with Java
               | (the language).
               | 
               | More features in Java (the language) gives other JVM
               | languages a larger set of tools to design interop support
               | around, while letting them remain a place for these
               | features to incubate without the headache of the JEP.
               | Sometimes these language-level changes may come with
               | modifications to the JVM to support them as well, letting
               | other languages clean up their implementations.
               | 
               | The whole situation works pretty well IMO.
        
           | srparish wrote:
           | Any word on when some of project amber features will come out
           | of preview? I get excited each JVM release for some of those
           | features, but it seems like most of the releases the preview
           | count just gets bumped, and a few more get added to the
           | preview holding pattern.
        
             | pron wrote:
             | Text blocks, var, records, sealed classes, and pattern
             | matching in instanceof have been out of preview for some
             | time, but two more features -- record patterns
             | (https://openjdk.org/jeps/440) and pattern matching in
             | switch (https://openjdk.org/jeps/441) -- are about to come
             | out of preview.
        
           | gigatexal wrote:
           | Very cool!
        
         | dgf49 wrote:
         | So your (general) complaints are all you do add to this when
         | others try to create things to help others?
        
         | therealdrag0 wrote:
         | Going from Java 8 to Scala was mind melting. Would never want
         | to go back. Though I've heard later versions of Java are
         | better. And katlin seems like an in between.
        
           | usrusr wrote:
           | Or stick to kotlin and keep the mind conveniently solid ;)
           | 
           | I was one of the Bored Scala Crowd in the audience of a
           | presentation by jetbrains people that must have been not too
           | long after 1.0, took me half a decade to accept that a "poor
           | man's scala" is actually the language that I want.
        
             | therealdrag0 wrote:
             | Ya I'd love to give it a try. Probably will prioritize it
             | for next job Switch.
        
           | whatisthiseven wrote:
           | Yea, I'd imagine comparing a 9 year old version of a language
           | to another would be "mind melting". And you are comparing to
           | Java 8, from before Java re-organized their JEP process to
           | ship features far faster, with a different release philosophy
           | and feature roadmap.
           | 
           | Kotlin is worth picking up, but after seeing the speed at
           | which Kotlin moves compared to how Java moves now, I don't
           | think Kotlin will keep up long term.
        
           | dboreham wrote:
           | Much prefer Kotlin to Scala myself. Forcing monadic
           | composition everywhere was a deal breaker for me. Same as the
           | viral async problem in JS, imho.
        
         | nogridbag wrote:
         | I've returned to Java after using Clojure and Groovy for
         | several years. I appreciate the fact that Java's just plain
         | boring and slightly verbose.
         | 
         | Most of the time the complexity in my code has little to do
         | with Java being verbose and more due to the business problem.
         | There are areas to improve and Java's been making great strides
         | recently. For example, in Java 21 we may finally have methods
         | like getFirst() and getLast() for lists (via JEP 431) instead
         | of the incredibly clunky list.get(list.size() - 1). Java also
         | recently added multi-line Strings and templating is coming
         | shortly. Streams and Optionals also reduce quite a bit of
         | boilerplate, e.g. Optional's map and ifPresent methods are
         | often elegant. Really I can't think of many other areas where
         | Java gets in the way. Our team is incredibly productive with
         | modern Java.
         | 
         | I think most developers actually write overly verbose code
         | regardless of the language. And it seems little to do with
         | years experience. This youtube channel covers most of the
         | basics:
         | 
         | https://www.youtube.com/@CodeAesthetic
         | 
         | To me I just follow these recommendations naturally but in most
         | PRs I review there's often huge amounts of overly nested code,
         | poorly named methods, etc.
        
           | ithrow wrote:
           | What do you miss from Clojure?
           | 
           | BTW, is that your channel?
        
             | nogridbag wrote:
             | Not my youtube channel. It just showed up in my recommended
             | videos and it seemed like good advice (common sense). It's
             | helpful to point devs to those videos when I see them
             | making those types of mistakes.
             | 
             | I miss the data oriented approach Clojure libraries take. I
             | remember having an issue with Ring and I just dove into the
             | Ring source code and it was so simple and clear and I found
             | the solution to my issue in minutes. I've never had that
             | experience with Java and instead resort to forums,
             | stackoverflow, etc. Most Java libraries would have several
             | layers of abstraction and they're often intimidating. I
             | consider myself an amateur Clojure dev and yet still
             | contributed some PRs to some projects.
             | 
             | With that said, I've written some internal tools in Clojure
             | and it was a nightmare whenever I had to modify them. They
             | were pretty simple CLI tools that only needed updates every
             | 6 months or so. I usually have to spin up the project with
             | a repl just to understand the inputs and outputs to
             | functions. I've ported all internal tools I created at my
             | current company from Clojure to Java and I personally find
             | them so much easier to maintain.
        
         | ludovicianul wrote:
         | As the classic saying says: there are languages everyone
         | complains about and languages that are not (actually) used.
         | Verbosity is usually a _good_ think especially in large code
         | bases with large number of people (where every successful
         | startup will eventually get)
        
           | alfalfasprout wrote:
           | The longstanding lack of generics (which has been remedied
           | aside) who really complains about golang?
           | 
           | The reality is Java truly shows its age. Its dogmatic
           | insistance on pure OOP and the enormous numbers of
           | horrifyingly unintuitive design patterns adopted by the
           | community cause even the most well intentioned engineering
           | culture to eventually produce ugly codebases.
           | 
           | At this point if you're stuck in the JVM ecosystem you're
           | almost certainly better off with Scala (which indeed is
           | _actually_ used) or the newer Kotlin.
           | 
           | In a way, for all the shit people give C++ modern C++
           | codebases are actually quite pleasant and the language is
           | very flexible. Would I encourage its use for general
           | production systems? Not really. That crowns is Golang's.
        
           | oweiler wrote:
           | If verbosity would be a good thing Java wouldn't introduce
           | language features/ library enhancements to cut down the noise
           | (var, collection factories, switch expressions, records).
        
         | seanw444 wrote:
         | Agreed. Reading and writing Java code just really annoys me.
         | It's so ugly, in my opinion.
        
           | dboreham wrote:
           | Just for balance: after writing much Java years ago, then
           | moving on to mostly JS/TS, Scala and Kotlin, going back and
           | looking at old Java I forget writing, it looks very nice and
           | easy to understand.
        
             | dahfizz wrote:
             | >> It's so ugly
             | 
             | > nice and easy to understand
             | 
             | Java is definitely more practical than pretty. This
             | frustrates the trendy crowd, but I think its important for
             | tools to be practical. Shiny, pretty languages are never as
             | long-lived as practical "ugly" languages.
        
               | 5e92cb50239222b wrote:
               | If it scares away the "let's rewrite it in
               | language/framework of the day" crowd, that's a plus in my
               | book.
        
         | the_gipsy wrote:
         | Just try something else.
        
           | re-thc wrote:
           | And then you'll hear of it being "verbose" and "boring" too.
           | Grass is always greener...
        
             | eddsh1994 wrote:
             | You're not wrong. I've worked in prod with all the cool
             | languages (Scala, Haskell, Rust, Go, etc...) but stick to
             | Python/typeScript when I want to be pragmatic.
        
             | the_gipsy wrote:
             | But at least you remove the doubt. And Java is a special
             | case of objectively being browner.
        
       | ok_dad wrote:
       | Is there a good guide to learning modern Java? At my workplace,
       | we're thinking about using it for a few things from Python. I'm
       | not looking for a "Java for Python developers" but more like
       | "Java for people who already know about the basic structures of
       | programming languages". I would love to hear about variable
       | instantiating and for loops as little as possible to grok the
       | Java model of programming, then drive right into the meaty bits
       | of how Java programmers think today. I did Java 20 years ago in
       | college.
        
         | xdavidliu wrote:
         | I recommend The Core Java pair of books by Cay Horstmann,
         | supplemented by Effective Java by Bloch. Those are probably the
         | two most authoritative sources on Java out there, and both
         | highly readable.
         | 
         | I heard not so good things about Herb Schildt's book.
        
           | [deleted]
        
           | ptx wrote:
           | I second this recommendation! I read Horstmann's books
           | recently and they were excellent. He really puts things in
           | context - any time I was thinking "WTF? Why would they do
           | things this way?" he had an explanation coming up (or in some
           | cases an acknowledgment that it is indeed a WTF).
        
             | gleenn wrote:
             | Horstmann was one of my favorite teachers at San Jose
             | State. He's a really sharp guy, and very enthusiastic
             | teacher. I had him for a programming languages class and we
             | dove into the various implementations of closures that were
             | to be added to Java. We compared these to Scala and some
             | other languages. Really fun diving in with his explanations
             | along the way.
        
         | zikohh wrote:
         | In 2023 don't write java but kotlin code.
        
         | vijucat wrote:
         | Other have great recommendations. Two of mine:
         | 
         | 1. The Java Programming Language book:
         | 
         | The K&R of Java
         | 
         | https://www.amazon.com/Java-Programming-Language-4th/dp/0321...
         | 
         | 2. Zantorc's videos: https://www.youtube.com/@Zantorc/
         | 
         | He really gets into the nitty gritty. You can listen to this
         | while commuting, etc; Just finish 1 video per 3 days, say. It
         | adds up quickly.
        
         | alfalfasprout wrote:
         | Now in 2023 I'd strongly think twice before investing heavily
         | in Java. For the vast majority of use cases where Java is
         | utilized Go ends up being a better choice w/ cleaner codebases,
         | static binaries (none of this JDK/JRE deployment mess), and
         | phenomenal performance. Not to mention proper interop with
         | native (C/C++) code without JNI funny business.
        
           | matsemann wrote:
           | You talking about JDK/JRE deployment mess means you haven't
           | looked at java for 5+ years, as that's no longer an issue.
           | Hence it's hard to trust your advice when you're so off.
           | 
           | And no, the vast majority of use cases for java isn't
           | distributing binaries or interoping with JNI.
        
           | pron wrote:
           | No more JRE deployment mess (https://openjdk.org/jeps/282) --
           | in fact the JRE no longer exists; no more need for JNI
           | (https://openjdk.org/jeps/442).
           | 
           | Java in 2023 is not what you may remember.
        
           | slaymaker1907 wrote:
           | I work at Microsoft and I'd use Java (not even C# and yes at
           | work) a hundred times before I'd consider using Go again. Go
           | dependency management is a bit better these days, but the
           | build system is an absolute mess, logging is dreadful, and
           | IDE support seems pretty primitive. Also, Exceptions are
           | vastly superior for most services compared to returning an
           | error outside of a few edge cases since most of the time I
           | have no idea how to handle errors at the callsite and really
           | just need to handle any errors at a high level (like
           | reverting the transaction and returning an HTTP error code).
        
             | miohtama wrote:
             | Why do Go still insists no exceptions?
        
               | fweimer wrote:
               | Go has exceptions, with the usual stack unwinding. The
               | standard library does not use them (for the most part,
               | panics are sometimes used to simplify error handling
               | code, see encoding/gob). It's like Perl and Rust in this
               | regard. Undocumented exceptions/panics are often
               | considered security vulnerabilities by the Go team.
               | 
               | The argument against exceptions is that non-local control
               | flow can introduce obscure bugs, like forgetting to clean
               | up resources on the (invisible) exceptional execution
               | path. On the other hand, without exceptions, it's
               | possible to end up with no error handling at all by
               | accident, and that too is not visible in the source code
               | (but linters can help, of course).
               | 
               | Many languages which are anti-exception as a matter of
               | principle still use them to report out-of-memory
               | conditions, out-of-bounds array indices, integer division
               | by zero, or attempts to access absent optional values.
               | Not doing this results in code that is simply too
               | verbose.
        
           | pianoben wrote:
           | Having done in-depth work both with JNI and with cgo, I don't
           | agree that Go is without "funny business". Indeed, cgo leaves
           | a _lot_ to be desired IMO, especially if you with to
           | distribute a library for other projects to consume. The
           | interplay between native and managed code is also fairly
           | tricky.
        
           | whimsicalism wrote:
           | Simple binaries, terrible abstractions.
        
         | dxxvi wrote:
         | Have you ever heard of the book Core Java for the Impatient?
        
         | willbw wrote:
         | Effective Java by Joshua Bloch is fantastic for covering up to
         | Java 9. There have been incremental updates since then but this
         | book will get you 95% of the way, and it is very well written.
        
         | lenkite wrote:
         | "Java for Developers Pocket Primer" is a new book that ramps
         | you up fast (~200 pages) assuming you are already a developer
         | familiar with programming.
        
         | mikmoila wrote:
         | https://dev.java/
        
           | znpy wrote:
           | this looks awesome, thank you!
        
       ___________________________________________________________________
       (page generated 2023-03-17 23:01 UTC)