5 ms·
1843 options is too many. You could never even consider all of the possible combinations and interactions, let alone test them. I have really come to appreciat
by Hendrikto 7mo ago
1843 options is too many. You could never even consider all of the possible combinations and interactions, let alone test them.
I have really come to appreciate modern opinionated tooling like gofmt, that does not come with hundreds to thousands of knobs.
- tezza 7mo agoHow is this different to system tuning parameters in Linux /proc, FreeBsd, Windows Registry, Firefox about:config, sockopt, ioctl, postgres? Zillions of options. Some important, some not
- mzi 7mo agoOne of my nerd-quizzes I hade at interviews before was "what letters in what case are NOT flags to GNU ls".
- deepsun 7mo agoJust because you have more features and ways to use them. Say I like to use a different garbage collector for a tool.
- RadiozRadioz 7mo agoI don't think modernity is a noteworthy factor as to whether tooling is opinionated.
- elric 7mo agoIn what way is gofmt remotely comparable to a JVM? In reality the number of options is significantly smaller than the 1843 you mentioned. The list contains boatloads of duplicates because they exist for multiple architectures. E.g. BackgroundCompilation is present on 8 lines on the OpenJDK 25 page: aarch64, arm, ppc, riscv, s390, x86 and twice more without an architecture.
- avianlyric 7mo agogofmt isn’t really comparable to the JVM, but it is a really strong expression of the opinionated tooling GoLang has. While gofmt is “just” a formatting tool. The interesting part is that go code that doesn’t follow the go formatting standard is rejected by the go compiler. So not only does gofmt not have knobs, you can’t even fork it to add knobs, because the rest of the go ecosystem will outright reject code formatted in any other way. It’s a rather extreme approach to opinionated tooling. But you can’t argue with the results, nobody writing go on any project ever worries about code formatting.
- kfuse 7mo agoThey do worry, they just can't do anything about it. Like the fact that error handling code takes at least three lines no matter how trivial it is. I'm sure error handling would not be critisized nearly as much if it didn't consume so much vertical space and could fit in one line, which go compiler does allow.
- elric 7mo agoThat's all well and good, but entirely irrelevant to the number of options a JVM should reasonably have.
- bram98 7mo ago.
- parsd 7mo agoI don’t believe the Go compiler would reject unformatted code. The compiler has its own set of rules for what it views as syntactically correct code, but these rules have nothing to do with gofmt’s formatting rules. For example, it’s the compiler and not gofmt that dictates that you must write a curly brace only on the same line of an “if” statement. If you put it on the next line, you don’t have unformatted code - you have a syntax error. However, the compiler doesn’t care if you have too much whitespace between tokens or if you write your slice like []int{1, 2,3,4}, but gofmt does. We could say the rules of the compiler and gofmt don’t even overlap.
- tomaytotomato 7mo agoIt's a result of Java being required to run on many different OS environments (Oracle, Redhat, Windows, RISC/ARM/x86), along with user constraints and also business requirements. In a way you can use this list of JVM options to illustrate how successful Java has become, that everyone needs an option to get it to work how they like it. As a Java dev, I have maybe used about 10-15 of them in my career. The weirdest/funnest one I used was for an old Sun Microsystems Solaris server which ran iPlanet, for a Java EE service. Since this shared resources with some other back of office systems, it was prone to run out of memory. Luckily there was a JVM option to handle this! -XX:OnOutOfMemoryError="<run command>" It wasn't too important so we just used to trigger it to restart the whole machine, and it would come back to life. Sometimes we used to mess about and get it to send funny IRC messages like "Immah eaten all your bytez I ded now, please reboot me"
- nkzd 7mo agoWhich JVM options do you use the most?
- cogman10 7mo agoHeap size, GC algorithm. I suggest most people never touch almost any other options. (Flight recording and heap dumps being the exception).
- marginalia_nu 7mo agoGC threads are generally often useful on multi-tenant systems or machines with many cores, as Java will default-size its thread pools according to the number of logical cores. If the server has 16 or more cores, that's very rarely something you want, especially if you run multiple JVMs on the same host. Not JVM options, but these are often also good to tune: -Djdk.virtualThreadScheduler.parallelism -Djdk.virtualThreadScheduler.maxPoolSize -Djava.util.concurrent.ForkJoinPool.common.parallelism In my experience this often both saves memory and improves performance.
- 7mo ago
- eru 7mo ago> You could never even consider all of the possible combinations and interactions, let alone test them. Nobody has ever tested all possible inputs to 64 bit multiplication either. You can sample from the space.
- pixl97 7mo agoEh that sounds a bit different to me, multiplication should be roughly the same operator on each test, these are wildly different functions.
- deepsun 7mo agoYou forgot about NaNs (all of them), infinities and positive/negative zeros. Tests warranted.
- MaxBarraclough 7mo agoDon't forget the Intel floating-point division bug from the 90s. https://en.wikipedia.org/wiki/Pentium_FDIV_bug https://en.wikipedia.org/wiki/Pentium_FDIV_bug
- eru 7mo agoI was being a bit hyperbolic. However, sampling really is the way to go when you face a combinatorial explosion. (If you can't prove it correct, that is.)
- Geezus_42 7mo agoAs a sysadmin, not developer, I hate Java almost as much as Windows. The error messages Java apps produce are like coded messages that you have to decipher. I.E. Instead of "<DOMAIN> TLS Handshake failed" it will be something like "ERROR: PKIX failed". So now I have to figure out that PKIX is referring to PKI and it would make too much sense to provide the domain that failed. Instead I have to play the guessing game.
- deepsun 7mo agoI hate when tools only produce generic "TLS Handshake failed" instead of saying why exactly it failed, where is the problem.
- thunky 7mo agoSounds like you'd both be happy if the tool produced both.
- appplication 7mo agoThis is why stack traces exist. But I agree Java seems to not really have a culture of “make the error message helpful”, but instead preferring “make the error message minimal and factual”. For what it’s worth, the rise of helpful error messages seems to be a relatively new phenomenon the last few years.
- Geezus_42 7mo agoA stack trace that is >10 pages in less is not what I would call minimal.
- deepsun 6mo agoAnd that's why you should have multiple appenders. So in code you write "log.error("...", exception)" once, but logging writes it in parallel to: 1. STDOUT for quick and easy look, short format. 2. File as JSON for node-local collectors. 3. Proper logging storage like VictoriaLogs/Traces for distributed logging. Each appender has its own format, some print only short messages, others full stacktraces for all causes (and with extra context information like trace id, customer id etc). I really think STDOUT-only logging is trying to squeeze different purposes into one unformatted stream. (And Go writing everything to STDERR was a really strange choice). https://www.baeldung.com/logback#bd-appenders https://www.baeldung.com/logback#bd-appenders
- pron 7mo agoThese are all the options that have ever existed, including options that are or were available only in debug builds used during development and diagnostic options. There are still a few hundred non-diagnostic "product" flags at any one time, but most are intentionally undocumented (the list is compiled from the source code [1]) and are similar in spirit to compiler/linker configuration flags (only in Java, compilation and linking are done at runtime) and they're mostly concerned with various resource constants. It is very rare for most of them to ever be set manually, but if there's some unusual environment or condition, they can be helpful. [1]: https://github.com/openjdk/jdk/blob/master/src/hotspot/share/runtime/globals.hpp https://github.com/openjdk/jdk/blob/master/src/hotspot/share...
- quotemstr 7mo agoIn the age of LLMs coupled with open source software, option count is unlimited. I fork FOSS projects and modify them for my own use all the time. Sometimes, with an agent, doing so is even easier than finding the "right" knob.
- fHr 7mo agoThank god you have no say in where modern tooling is heading, at the creator of the site, absolute right choice to leave it up to the user to chose all options.
- TacticalCoder 7mo ago> 1843 options is too many. You could never even consider all of the possible combinations and interactions, let alone test them. You can search for those that may concern you. Good old search or AI "search". For example I recently did test the AOT compilation of Clojure (on top of the JVM) code using "Leyden". I used an abandoned Github project as a base but all the JVM parameters related to Leyden had changed names (!) and the procedure had to be adapted. I did it all (as a Dockerfile) in less than an hour with Sonnet 4.6 (complete with downloading/verifying the Leyden JVM, testing, taking notes about the project, testing on different machines, etc.). These are not trivial calls to the "java" command: it involves a specific JVM and several JVM params that have to work fine together. The goal was to load 80 000 Clojure/java classes (not my idea: the original project did that part) and see the results: 1.5 seconds to launch with the Leyden JVM (and correct params) vs 6 seconds for a regular launch (so a 75% gain). GraalVM is even faster but much more complicated/annoying to get right. It can look overwhelming but I'd say all these parameters are there for a reason and you only need a few of them. But when you need them, you need them. P.S: unrelated to TFA and as a bonus for the "Java is slow crowd": time java -jar hello/hello.jar Hello, World! real 0m0.040s And that's without any Leyden/GraalVM trick. For Clojure the "slow" startup times are due to each Clojure function being transformed into one Java .class each and there are many Clojure functions. Hence the test with 80 000 Clojure functions from the project I reused: https://github.com/jarppe/clojure-app-startup-time-test https://github.com/jarppe/clojure-app-startup-time-test (but it's not maintained, won't work as if with the latest Leyden JVM)
- vips7L 7mo agoI could be missing it because I’m not that familiar with bb, but looking at your repository it doesn’t look like you’re using any feature that was actually shipped with project Leyden. It looks like you’re just using AppCDS which has been around for a long time.
- TacticalCoder 7mo agoAh it's not my repository (I don't have any public repo FWIW): it's a repository I stumbled upon and I decided to port it to a more recent version of the Leyden JVM (using proper AOT, not the very old CDS). I re-used it for I found it's approach to generating 80 000 Clojure classes to then test bare JVM vs Leyden AOT vs full GraalVM startup timing interesting.
- jmyeet 7mo agoWasn't it Joel Spolsky who said every option is a cop out? Or maybe Steve Yegge? I forget. It's something I agree with. I often have this thought when going through the options of something conceptually fairly simple: "who is this for? who actually uses this option?" I kinda feel the same way with C/C++ warnings. Different code bases decide if different warnings are errors. That was a mistake (IMHO). The other thought I have scanning these options is how many are related to GC. I kinda think GC is a bit of a false economy. It's just hiding the complexity. I wonder if it would've been better to push GC to be pluggable rather than relying on a host of options, a bit like TCP congestion management. I mean there are /proc parameters for that in Linux, for example, but it's also segregated (eg using BRR). At the end of the day, none of this really matters. As in, the JVM is mature and I think generally respected.
- vips7L 7mo agoThe GC is pluggable, that’s why you have so many to choose from depending on your work load. You rarely if ever have to touch those options. In the last 10 years all of my apps, since I run on a modern version of Java, only ever set max heap size and soon that will (finally) be figured out automatically: https://openjdk.org/jeps/8359211 https://openjdk.org/jeps/8359211
- izacus 7mo agoJoe Spolsky also never created anything as popular and widely deployed as Java. It's easy to bloviate about pure software when it doesn't need to literally run the whole world as you know it.
- toyg 7mo agoEr. IIRC, Spolsky was involved in creating VBA for Excel. Which was arguably orders of magnitude more popular (and still more widely deployed and world-supporting) than Java.
- izacus 7mo agoIn the 90s, as a program manager. And it's a big difference between building an application and a platform (I've done both) when it comes to API design.
- pjmlp 7mo agoHave you ever seen how many GCC has for plain old C?
- Hendrikto 7mo agoYeah, that’s a mistake too, and a big reason for why compiling C projects is such a pain. Notice how I did not compare to C, but modern alternatives.
- pjmlp 7mo agoGccgo and tinygo do exist, with enough parameters.
- pron 7mo agoI'll grant you that Go is extremely opinionated; that's its shtick. But it's an old language that started out with a 1970s design as a statement by its creators against modern programming languages. From its langnauge design, through its compiler, to its GC algorithm, it is intentionally retro (Java retired its Go-like GC five years ago because the algorithm was too antiquated). It may suit your taste and I'm not suggesting that it's bad, but modern it is not.
- layer8 7mo agoThe comparison with gofmt makes no sense. If Go had myriads of compiler implementations (the analogy being target environments for the JVM) that all had different performance characteristics and other behavioral differences depending on how the source code is formatted, you bet that gofmt would have a lot of options as well. The JVM is like an operating system. A better comparison would be Linux kernel parameters: https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html https://www.kernel.org/doc/html/latest/admin-guide/kernel-pa...
- ncruces 7mo agoI appreciate the philosophy behind Go as much as anyone, but this comment sounds tone deaf, and indicative of a certain immaturity. Many of these flags are the equivalent of GODEBUG. GODEBUG does not have 1843 options, but do you know how many it has? Have you ever used GODEBUG? (I'm guessing no, hence, immaturity) And if not, do you think it should just be dropped because you never needed it?