6 ms·
> and it feels bloated (Java!) I'm curious, what exactly feels bloated about Java? I don't feel like the Java language or runtime are particularly bloated, so
by njitbew 1y ago
> and it feels bloated (Java!)
I'm curious, what exactly feels bloated about Java? I don't feel like the Java language or runtime are particularly bloated, so I'm guessing you're referring to some practices/principles that you often see around Java software?
- slipperydippery 1y agoWhatever efficiency may hypothetically be possible with Java, you can in-fact spot a real world Java program in the wild by looking for the thing taking up 10x the memory it seems like it should need… when idle. Yes yes I’m sure there are exceptions somewhere but I’ve been reading Java fans using benchmarks to try to convince me that I can’t tell which programs on my computer are Java just by looking for the weirdly slow ones, when I in fact very much could, for 25ish years. Java programs have a feel and it’s “stuttery resource hog”. Whatever may be possible with the platform, that’s the real-world experience.
- MathMonkeyMan 1y agoThe JVM eats a chunk of memory in order to make its garbage collector more efficient. Think of it like Linux's page cache. I haven't worked with too much Java, but I suspect that the distaste many have for it is due to its wide adoption by large organizations and the obfuscating "dressed up" tendency of the coding idioms used in large organizations. The runtime isn't inherently slow, but maybe it's easier to write slow programs in Java.
- bdangubic 1y agoyou know why you don’t see many non-Java programs on your computer taking up 10x memory? because no one uses them to write anything :) jokes aside, we got a shift in the industry where many java programs were replaced by electron-like programs which now take 20x memory
- js4ever 1y ago[flagged]
- p2detar 1y agoIs this an AI-generated answer? Most of these are not even true, although I still would prefer Go for micro-services. I'll address just a bunch and to be clear - I'm not even a big Java fan. - Quarkus with GraalVM compiles your Java app to native code. There is no JIT or warm up, memory footprint is also low. By the way, the JVM Hotspot JIT can actually make your Java app faster than your Go or Rust app in many cases [citation needed] exactly due to the hot path optimizations it does. - GC tuning - I don't even know who does this. Maybe Netflix or some trading shops? Almost no one does this nowadays and with the new JVM ZGC [0] coming up, nobody would need to. > You can’t ship a minimal standalone binary without pulling in a JVM. - You'd need JRE actually, e.g., 27 MB .MSI for Windows. That's probably the easiest thing to install today and if you do this via your package manager, you also get regular security fixes. Build tools like Gradle generate a fully ready-to-execute directory structure for your app. If you got the JRE on your system, it will run. > Dependency management and classpath conflicts historically plagued Java The keyword here is "historically". Please try Maven or Gradle today and enjoy the modern dependency management. It just works. I won't delve into Java 9 modules, but it's been ages since I last saw a class path issue. > J2EE Is someone still using this? It is super easy writing a web app with Java+Javalin for example. The Java library and frameworks ecosystem is super rich. > “Write once, run anywhere” costs: The abstraction layers that make Java portable also add runtime weight and overhead. Like I wrote above, the HotSpot JIT is actually doing the heavy lifting for your in real time. These claims are baseless without pointing to what "overhead" is meant in practice. --- 0 - https://inside.java/2023/11/28/gen-zgc-explainer/ https://inside.java/2023/11/28/gen-zgc-explainer/ or https://www.youtube.com/watch?v=dSLe6G3_JmE https://www.youtube.com/watch?v=dSLe6G3_JmE
- vips7L 1y ago> GC tuning, Netflix I believe Netflix has moved to ZGC with no tuning. Their default setup is to set the min/max heap to the same size, enable always pretouch, and to use transparent huge pages [0]. GC tuning is something of the past. Once automatic heap sizing for ZGC and G1 land you won’t even need to set the heap size [1][2]. They’ll still use more ram because the vm and jit, but the days of it holding on to ram when it doesn’t need it should be over. [0] https://netflixtechblog.com/bending-pause-times-to-your-will-with-generational-zgc-256629c9386b https://netflixtechblog.com/bending-pause-times-to-your-will... [1] https://openjdk.org/jeps/8329758 https://openjdk.org/jeps/8329758 [2] https://openjdk.org/jeps/8359211 https://openjdk.org/jeps/8359211
- vlovich123 1y agoTechnically kind of true but at the same time Android apps are predominantly Java/Kotlin. It speaks more to Java just having a bad desktop story. But it’s also why Android devices need 2x the ram
- vips7L 1y agoThat has nothing to do with Java. The Android runtime is NOT Java/OpenJdk.
- vlovich123 1y agoNo but it does speak to the memory overhead of tracing GC vs ref counting as garbage collection strategies.
- gf000 1y agoWhich is very important in... embedded settings. While for typical backend situations, reference counting has a crazy high throughput overhead, doing atomic inc/decs left and right, that instantly trashes any kind of cache, and does it in the mutator thread that would do the actual work, for the negligible benefit of using less memory. Meanwhile a tracing GC can do (almost) all its work in another thread, not slowing down the actually important business task, and with generational GCs cleaning up is basically a no-op (of just saying that this region can now be reused). It's a tradeoff as everything in IT. Also, iPhone CPUs are always a generation ahead, than any android CPU, if not more. So it's not really Apples to oranges.
- zozbot234 1y agoIt depends how you implement reference counting. In Rust the atomic inc-dec operations can be kept at a minimum (i.e. only for true changes in lifecycle ownership) because most accesses are validated at compile time by the borrow checker.
- vlovich123 1y agoThat would be a compelling counter if and only if languages like Java actually beat other languages in throughput. In practice that doesn’t seem to be the case and the reasons for that seem to be: * languages like c++ and Rust simply don’t allocate as much as Java, instead using value types. Even C# is better here with value types being better integrated. * languages like c++ and Rust do not force atomic reference counting. Rust even offers non atomic ref counting in the standard library. You also only need to atomic increment / decrement when ownership is being transferred to a thread - that isn’t quite as common depending on the structure of your code. Even swift doesn’t do too badly here because of the combination of compiler being able to prove the permission of eliding the need for reference counting altogether and offering escape hatches of data types that don’t need it. * c++, Rust, and Swift can access lower level capabilities (eg SIMD and atomics) that let them get significantly higher throughput. * Java’s memory model implies and requires the JVM to insert atomic accesses all over the place you wouldn’t expect (eg reading an integer field of a class is an atomic read and writing it is an atomic write). This is going to absolutely swamp any advantage of the GC. Additionally, a lot of Java code declares methods synchronized which requires taking a “global” lock on the object which is expensive and pessimistic for performance as compared with the fine-grained access other languages offer. * there’s lots of research into ways of offering atomic reference counts more cheaply (called biased RC) which can safely avoid needing to do an atomic operation in places completely transparently and safely provided the conditions are met . I’ve yet to see a Java program that actually gets higher throughput than Rust so the theoretical performance advantage you claim doesn’t appear to manifest in practice.
- jghn 1y ago> taking up 10x the memory it seems like it should need… when idle. The JVM tends to hold onto memory in order to make things faster when it does wind up needing that memory for actual stuff. However, how much it holds on to, how the GC is setup, etc are all tunable parameters. Further, if it's holding onto memory that's not being used, these are prime candidates to be stored in virtual memory which is effectively free.
- jayd16 1y ago"Java is bloated because I only look at the bloated examples." Is C++ bloated because of the memory Chrome uses?
- slipperydippery 1y agoWhen all your examples in actual use are bloated… I’ve never seen another basic tech used to develop other programs that’s so consistently obvious from its high resource use and slowness, aside from the modern web platform (Chrome, as you put it). It was even more obvious back when we had slower machines, of course, but Java still stands out. It may be able to calculate digits of Pi in a tight loop about as fast as C, but real programs are bloated and slow.
- gf000 1y agoSounds like a classic case of confirmation bias. Especially that like half of the web runs on Java, you just have absolutely no idea when it silently does its job perfectly.
- slipperydippery 1y agoK.
- alt227 1y ago> Especially that like half of the web runs on Java Source? W3 seems to think its more like ~5% https://w3techs.com/technologies/comparison/pl-java https://w3techs.com/technologies/comparison/pl-java
- gf000 1y ago5% of "whose server-side programming language we know" From the website. And 76% of these websites is PHP, which seems to mean.. they can determine PHP more easily for a website (nonetheless, there are indeed a lot of WordPress sites, but not this amount).
- mldbk 1y agoI held the same view as you when I was 22, more than 15 years ago. With over 15 years of professional experience since then, my perspective has shifted: Java demonstrates its strength when stability, performance, and scalability are required (e.g. bloody enterprise) A common misconception comes from superficial benchmarking. Many focus solely on memory consumption, which often provides a distorted picture of actual system efficiency. I can point to EU-scale platforms that have reliably served over 100 million users for more than a decade without significant issues. The bottleneck is rarely the language itself, it is the depth of the team’s experience.
- edem 1y agonode is a notable exception. Compared to java node is a hellhole. the standard library is non-existent, most libraries are a buggy mess, the build system is horrible...in fact there is no reliable build system that solves all your typical problems in 1 app. The list goes on.
- alt227 1y ago> Many focus solely on memory consumption, which often provides a distorted picture of actual system efficiency. When other languages can do the same thing with an order of magnitude less RAM, any other efficencies in the system tend to be overshadowed by that and be the sticking point in peoples memories. You may argue that holding on to this extra memory makes subsequent calls and reads quicker etc, but in my experience generally people are willing to sacrifice milliseconds to gain gigabytes of memory.
- gf000 1y agoWell, you might want to read up on how OSs handle memory under the hood, and that virtual memory != physical, and that task manager and stuff like that can't show the real memory usage. Nonetheless, tracing GCs do have some memory overhead in exchange for better throughput. This is basically the same concept as using a buffer. ----- And can you tell which of these websites use Java from "the feel"? AWS cloud infra, a significant chunk of Google, Apple's backends, Alibaba, Netflix?
- edem 1y agoNote that the memory problem you mentioned is not really a problem in fact. It is just how managed memory works in Java. Just run .gc() and you'll see what I'm talking about. It reserves memory which you can see on the charts but it is not necessarily used memory.
- poemxo 1y agoStarting up a Java program takes much longer than it should and that affects perception.
- halfmatthalfcat 1y agoWith AOT tho that should be somewhat moot.
- poemxo 1y agoI am just explaining why it has that reputation.
- edem 1y agoDepends on the program (especially the framework used) and the GC being used. I can write a java program and set it up in a way that it runs faster than almost everything else. For example in a serverless architecture where you need fast startup and small programs you can choose __not__ to use a GC and run ephemeral Java scripts. It starts and finishes running faster than you can blink.
- nova22033 1y agoIt may affect developer perception but I'm pretty sure my users don't notice and don't care.
- buckle8017 1y agoJava the language and Java the runtime are fine. The way most Java code is written is terrible Enterprise factory factory factory.
- vlovich123 1y agoBut 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.
- jghn 1y agoThis 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 1y agoFor many applications deferred garbage collection is acceptable. Worse latency every ten minutes tends to be fine.
- gf000 1y agoThere 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).
- rvz 1y ago> I'm curious, what exactly feels bloated about Java? Everything. Why do you think Kubernetes is NOT written in Java?
- AtlasBarfed 1y ago... Because it came from Google? Golang has little to distinguish itself technically. It has a more modern std lib (for now) and isn't Oracle. Which aren't trivial, but they aren't Trump cards.
- rvz 1y ago> ... Because it came from Google? Nope. None of what you said are any of the reasons given that it WAS written in Java already [0] but rewrote it all in Go explicitly because of its performance, concurrency and single binary distribution characteristics. Those were enough technical advantages to abandon any thought of a production-grade version of k8s in Java. [0] https://archive.fosdem.org/2019/schedule/event/kubernetesclusterfuck/ https://archive.fosdem.org/2019/schedule/event/kubernetesclu...
- vips7L 1y ago> the anti patterns weren’t enough we also observe how Kubernetes has over 20 main() functions in a monolithic “build” directory. We learn how Kubernetes successfully made vendoring even more challenging than it already was, and discuss the pitfalls with this design. We look at what it would take to begin undoing the spaghetti code that is the various Kubernetes binaries built from github.com/kubernetes/kubernetes It seems to me that perhaps it wasn’t the languages fault but the authors.
- gf000 1y ago> rewrote it all in Go explicitly because of its performance Because someone wanted a new, shiny toy.
- cameronh90 1y ago> what exactly feels bloated about Java? https://docs.spring.io/spring-framework/docs/2.5.x/javadoc-api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html https://docs.spring.io/spring-framework/docs/2.5.x/javadoc-a...
- dcminter 1y agoKafka does not use Spring.
- burnt-resistor 1y agoHave you ever run on-prem Atlassian products or any enterprise JVM apps? They hog RAM, are slow, and are a bitch to configure.