3 ms·
Many times the "massive" memory sink is because people give the VM more memory than it actually needs (or they use the default, which is to take up to 25% of RA
by pron 2y ago
Many times the "massive" memory sink is because people give the VM more memory than it actually needs (or they use the default, which is to take up to 25% of RAM whether or not it's really needed for the required performance). I.e. people will say a process "takes" 1gb, when the same program could run just as well if they tell it to use, say, 300mb. The more memory, the faster it could run. The GCs offered by the JVM are more advanced than Go's by a couple of tech generations (the Go-like GC was removed from the JVM when it was superseded by two generations of newer GCs), and memory consumption is already going down with compact object headers [1] and will go down even further with Valhalla.
All in all, Go may take up a little less memory for similar performance, but the JVM is more flexible (and more observable), offering you better performance if you need it. And the footprint will continue dropping, as it has done for years [2].
C++, Zig, or Rust are not really an apples-to-apples comparison. Sure, they take up significantly less RAM, but their performance is more expensive per unit of effort, and it's not a one-time cost, either. It's a permanent tax on maintenance, not to mention Java's superb observability.
Don't get me wrong -- I'm a fan of Zig, and C++ is the language I still program in most, but you can't really compare them to Java. Java makes you pay for certain things -- especially in RAM -- but you do get your memory's worth in exchange, and in a way that translates to pretty significant time and money. If you can't spare the memory as you're running in a constrained environment that's one thing, but if you can, it's all a matter of what you want to use it for: do you want to use it all just on data, or do you want to spare some to reduce maintenance costs/increase development speed and improve performance?
BTW, I'm not sure what is actually meant by a "lack of runtime" for C++/Rust/Zig. They all have standard libraries, just like Java. Rust even has a (crude) GC in its runtime that most Rust programs use (and, like Java, it compiles down to a VM). I think what people mean is that compilation to native is typically AOT rather than JIT, but that has both pros and cons.
[1]: https://openjdk.org/jeps/450 https://openjdk.org/jeps/450
[2]: E.g. https://openjdk.org/jeps/254 https://openjdk.org/jeps/254
- needlesslygrim 2y agoI'm interested by your characterisation of Rust. I assume 'crude GC' is a reference to Rc/Arc, but I would be interested to see some statistics for the claim most programs written in Rust use them extensively. Also, Rc/Arc arent a part of any Rust 'runtime', but rather the standard library, and are not available when they eould not be suitable for the target, e.g. UEFI. Moreover, rustc compiles to LLVM IR, but LLVM is not a JVM/CLR VM, and rustc is not the only Rust compiler (though the others are admittedly not production-ready yet).
- pron 2y ago> I assume 'crude GC' is a reference to Rc/Arc, but I would be interested to see some statistics for the claim most programs written in Rust use them extensively. Yes, Rust's GC is used through Rc/Arc, and I never said it is used extensively by most programs, only that most programs do use it. It is because it is not used extensively that it can be crude and designed to minimise footprint rather than offer good performance. > Also, Rc/Arc arent a part of any Rust 'runtime', but rather the standard library What's the difference between a standard library and a runtime? In the three decades I've been programming, they've been used interchangeably. A language runtime means some precompiled-code that programs use but is not compiled directly from the program. > rustc compiles to LLVM IR, but LLVM is not a JVM/CLR VM I never said that LLVM was a JVM -- these virtual machines have very different instruction sets -- but like a JVM, LLVM is a VM, i.e. an instruction set for an abstract machine. Now, it is true that Rust is typically (though not always) compiled to native code AOT while Java code is typically (though not always) compiled to native code JIT, but I don't understand why that difference is stated in terms of having a runtime. One could have an AOT-compiled JVM (and, indeed, that exists) as well as a JIT-compiled LLVM (and that exists, too). It is also true that Rust programs can be compiled without a runtime (or a very minimal one) while Java programs can choose to have more or less in their runtime, but even the most minimal runtime is larger than the most minimal Rust runtime.
- whytevuhuni 2y ago> What's the difference between a standard library and a runtime? In the three decades I've been programming, they've been used interchangeably. First of all, you're right. But despite its definition I think people tend to look at it differently. A runtime is generally thought of as a platform on top of which your code runs on; it needs to start first, and it manages your code. Or perhaps it runs in a side thread. A language that has a runtime is hard to embed into something via just the C ABI, because a function call wouldn't use just the standard platform calling convention; it would have to start that runtime, perhaps marshal the parameters into something supported by that runtime, and then finally the runtime runs your function's code. Take for example cgo, for which you'd need to start the garbage collector first (among other things), hence why the cgo FFI is expensive. Take as another example an async Rust function, which would require e.g. a Tokio runtime to be started first. Another example is Java, for which you'd have to start the whole JVM first. A language that has no runtime, or a minimal runtime, can be called via the C ABI directly. All the function needs is to follow the calling convention, and then its code starts running immediately. This is just my opinion of other people's opinions, I may be wrong.