Remix.run Logo
buckle8017 4 days ago

Java the language and Java the runtime are fine.

The way most Java code is written is terrible Enterprise factory factory factory.

throwaway8242 4 days ago | parent | next [-]

That doesn't match my experience in the last 15 years working for 3 companies (one was a big enterprise, one medium sized and one startup)

Maybe I have been lucky, or that the practice is more common in certain countries or eco systems? Java has been a very productive language for me, and the code has been far from the forced pattern usage that I have read horror stories about.

chamomeal 3 days ago | parent [-]

Have you gotten to use loom/virtual threads? I’ve heard pretty interesting stuff about em, but haven’t really spent the time to get into it yet. It’s pretty exciting and tbh gives me an easy elevator pitch to JVM world for people outside of it

62951413 2 days ago | parent [-]

If you have a use-case where you currently allocate ~1K threads mostly waiting on I/O switching to virtual threads is a one-liner ("Thread.ofVirtual()" instead of "Thread.ofPlatform()"). No more golang envy for sure.

Depending on how much memory is used by the Thread stack (presumably 1M-512K by default, allegedly 128K with Alpine base images) that's your 1G-500M heap space usage improvement right off the bat.

The migration from JDK17 to JDK21 was uneventful in production. The only issue is limited monitoring as a thread dump will not show most virtual threads and the micrometer metrics will not even collect the total number of active virtual threads. It's supposed to work better in JDK24.

The Spring Framework directly supports virtual threads with "spring.threads.virtual.enabled=true" but I haven't tried it to comment.

vlovich123 4 days ago | parent | prev | next [-]

But the perf is not reliable. If you want latency and throughput, idiomatic Rust will give you better properties. Interestingly even will Go for some reason has better latency guarantees I believe even though it’s GC is worse than Java.

gf000 3 days ago | parent | next [-]

There is not much point talking about throughput and latency in the abstract - they are very often opposing goals, you can make one better at the expense of the other.

Go's GC is tuned more for latency at the expense of throughput (not sure if it still applies, but Go was quite literally stopping the "business" mutator threads when utilisation got higher to be able to keep up with the load - Java's default GC is tuned for a more balanced approach, but it can deliver it at very high congestion rates as well. Plus it has a low-latency focused GC which has much better latency guarantees, and it trades off some throughput in a consistent manner, so you can choose what fits best). The reason it might sometimes be more efficient than Java is simply value types - it doesn't create as much garbage, so doesn't need as good a GC in certain settings.

Rust code can indeed be better at both metrics for a particular application, but it is not automatically true, e.g. if the requirements have funny lifetimes and you put a bunch of ARC's, then you might actually end up worse than a modern tracing GC could do. Also, future changes to the lifetimes may be more expensive (even though the compiler will guide you, you still have to make a lot of recursive changes all across the codebase, even if it might be a local change only in, say, Java), so for often changing requirements like most business software, it may not be the best choice (even though I absolutely love Rust).

jghn 4 days ago | parent | prev | next [-]

This presupposes the use case is such that this even matters. Obviously that is the case sometimes, but in the vast majority of cases it is not.

buckle8017 3 days ago | parent | prev [-]

For many applications deferred garbage collection is acceptable.

Worse latency every ten minutes tends to be fine.

gf000 3 days ago | parent | prev | next [-]

This is more of a meme, than reality. There are architecture astronauts for every platform and shitty code knows no bounds, regardless of language.

von_lohengramm 4 days ago | parent | prev [-]

The problem is that writing genuinely performant Java code requires that you drop most if not all of the niceties of writing Java. At that point, why write Java at all? Just find some other language that targets the JVM. But then you're already treading such DIY and frictionful waters that just adopting some other cross-platform language/runtime isn't the worst idea.

gf000 3 days ago | parent | next [-]

> The problem is that writing genuinely performant Java code requires that you drop most if not all of the niceties of writing Java

Such as? The only area where you have to "drop" features is high-frequency trading, where they often want to reach a steady-state for the trading interval with absolutely no allocations. But for HFT you would have to do serious tradeoffs for every language.

In my experience, vanilla java is more than fine for almost every application - you might just benchmark your code and maybe add some int arrays over an Integer list, but Java's GC is an absolute beast, you don't have to baby it at all.

munksbeer 3 days ago | parent | prev [-]

>The problem is that writing genuinely performant Java code requires that you drop most if not all of the niceties of writing Java. At that point, why write Java at all?

The reason is quite well known. Supporting multiple languages is a cost. If you only have to support one language, everything is simpler and cheaper.

With Java, you can write elegant code these days, rely on ZGC, not really worry too much about GC and get excellent performance with quick development cycles for most of your use cases. Then with the same language and often in the same repo (monorepo is great) you can write smarter code for your hot path in a GC free manner and get phenomenal performance.

And you get that with only having one build system, one CI pipeline, one deployment system, some amazing profiling and monitoring tooling, a bunch of shared utility code that you don't have to duplicate, and a lot more benefits.

That's the reason to choose Java.

Of course, if you're truly into HFT space, then they'll be writing in C, C++ or on FPGAs.