31 ms·
The only problem Java has is experienced C programmers don't build servers from scratch with it yet. Once they take that responsibility, the debate will be ove
by bullen 4y ago
The only problem Java has is experienced C programmers don't build servers from scratch with it yet.
Once they take that responsibility, the debate will be over because:
"While I'm on the topic of concurrency I should mention my far too brief chat with Doug Lea. He commented that multi-threaded Java these days far outperforms C, due to the memory management and a garbage collector. If I recall correctly he said "only 12 times faster than C means you haven't started optimizing"." - Martin Fowler https://martinfowler.com/bliki/OOPSLA2005.html https://martinfowler.com/bliki/OOPSLA2005.html
"Many lock-free structures offer atomic-free read paths, notably concurrent containers in garbage collected languages, such as ConcurrentHashMap in Java. Languages without garbage collection have fewer straightforward options, mostly because safe memory reclamation is a hard problem..." - Travis Downs https://travisdowns.github.io/blog/2020/07/06/concurrency-costs.html https://travisdowns.github.io/blog/2020/07/06/concurrency-co...
"Inspired by the apparent success of Java's new memory model, many of the same people set out to define a similar memory model for C++, eventually adopted in C++11." - https://research.swtch.com/plmm https://research.swtch.com/plmm
This combined with the fact that Java doesn't crash and you can easily hot-deploy the classloader (maybe 100 lines) means nothing can compete that doesn't copy everything Java does VM + GC (hello C#, please don't downvote).
To use anything else (than JavaSE without heavy deps.) on the server is madness.
- nelsondev 4y agoThe p50 speed up from delaying memory management comes with a trade off, namely you get Garbage Collection pauses, bad p99, and spend your effort tuning the Garbage Collector instead of your code.
- xxpor 4y agoAn uncommon but not unheard method around that (in services that have diurnal patterns) is to throw memory at it and collect once a day during the down time. You can take the server out of service, restart it, and put it back in service.
- ska 4y agoI read this was semi-standard memory management in the early lisp machine days, because that gc was so slow.
- bitwize 4y agoEarly Lisp (even pre-lispm) had no GC at all -- it just allocated until it ran out. Memory reclamation was done by saving the heap to tape and then reading it back -- only live objects were saved. So it was kind of GC with extra steps; the first GC algorithms removed the steps.
- User23 4y agoTo this day the Common Lisp standard doesn’t require GC.
- lispm 4y agoNah, Lisp had GC in 1960 already. McCarthy invented the mark & sweep GC. Lisp I Programmers Manual, 1960 https://www.softwarepreservation.org/projects/LISP/book/LISP%20I%20Programmers%20Manual.pdf https://www.softwarepreservation.org/projects/LISP/book/LISP... Chapter 6.3, Page 95, The Free-Storage List and the Garbage Collector
- plandis 4y agoThis is kind of hard to do in practice unless you’re really watching where you’re allocating memory. It’s very easy in Java to end up accidentally throwing a bunch of allocated memory on the heap without realizing it. Fwiw, the JVM now has a noop garbage collector so this is easy enough to benchmark.
- vbezhenar 4y agoCan you provide an examples of accidentally allocating memory? The only example I'm aware of is autoboxing which is huge misfeature IMO.
- kaba0 4y agoDoes it really? With Java’s G1GC the only knob you may end up having to tune is the max target pause time - which pretty much chooses between better p50 and worse p99 va worse p50 and better p90 - aka throughput vs latency, that are almost inherently opposite ends of the same spectrum. It is not GC-specific that any improvement will fail to increase one of those. So the actual tradeoff is more whether you want better throughput or tail-latency. To improve the latter, you have a singular command line option of using ZGC as well.
- hedora 4y agoYou mean the integer parameter "-XX:MaxGCPauseMillis"? The name says it all. You can do over a dozen sync disk writes in a millisecond these days.
- kaba0 4y agoHave you seen the output of JVM flight recorder or some other tool used to observe memory allocation/reclamation patterns? The JVM is very lazy when it comes to GC - its algorithms are crazy good and can catch up with really high allocation rates as well. So the maximum pause time’s unit doesn’t really say much, and when it comes to dynamic memory allocation, the JVM is the best choice according to the biggest web services operating on terabyte sized heaps.
- kasperni 4y agoWith modern concurrent GCs such as ZGC [1] this is really not an issue for most people anymore. [1] https://inside.java/2022/05/30/sip053/#:~:text=ZGC%20was%20designed%20as%20a,a%20maximum%20of%2016%20TBs https://inside.java/2022/05/30/sip053/#:~:text=ZGC%20was%20d....
- philipkglass 4y agoWith Java 17 I found that using ZGC eliminated [1] the GC pauses that yield bad P99 latencies without any additional tuning. However, it has lower throughput than G1GC so your P50 advantages will diminish. [1] Reduced them to always well below 1 millisecond.
- cogman10 4y agoWhich is always the tradeoff with GC. You get to pick latency or throughput and you trade one for the other.
- kaba0 4y agoIn my experience, this is not related closely to GC and are apparent in many systems. A great book on optimizations explicitly mentions that “improving one aspect of performance may degrade another”.
- plandis 4y agoLow pause collectors exist explicitly for this purpose. ZGC and Shenandoah both trade throughput (more concurrent collections) for extremely low pause times: https://malloc.se/blog/zgc-jdk16 https://malloc.se/blog/zgc-jdk16
- nimrody 4y agoDoes that mean they also trade _memory_ for low pause times? Because, in our application, the memory required for avoiding significant GC pauses is at least 4x the amount of memory we actually need at any given time. This can be significant too.
- mabbo 4y agoThat sounds a lot like the complaints about Java from a decade ago. Have you used it lately? Java's GCs are incredible and you have a menu of algorithmic options that let you avoid whatever problem you're worried about.
- dboreham 4y agoThe JVM GC is fundamentally the same as 10 years ago.
- titzer 4y agoShenandoah did not exist 10 years ago, and G1 was not deployed.
- bitcharmer 4y agoSaying this just shows you don't know much about modern JVM.
- hackerlight 4y agoDo you use a proprietary JVM at your place?
- bitcharmer 4y agoNope. Only OpenJDK and Azul Prime.
- cogman10 4y ago10 years ago the algorithms you could pick were serial, parallel, and CMS. Today we've removed CMS, added G1GC, and added ZGC. G1GC is similar to the parallel in the way it operates but is divided up enough to control for latency. ZGC is fundamentally different from the parallel collector or G1GC. Suggesting it is the same is to suggest you know nothing of the changes that have happened.
- jcelerier 4y ago
- titzer 4y ago> tuning the Garbage Collector instead of your code. This is a feature, not a bug. Which is riskier?
- cogman10 4y agoNow-a-days, if you are tuning your GC you are almost certainly doing the wrong thing. While the JVM offers a plethora of levers to pull in case you are hyper concerned about different things, the heuristics are VERY good. Mucking with the fine grained details can disable heuristics and ultimately give you worse results than if you just left stuff alone. The levers to pull are algorithm, max memory, and max pause time. All other levers should be left alone unless you've got GC logs to back up what you think needs changing. (And even then... Do you really?) Typically, the better route is flight recorder and eliminating wasted allocations.
- xxs 4y ago> Garbage Collection pauses True concurrent GC have been available since late 2000s. Azul had a read-barrier GC as well - effectively a pauseless GC (or pauses under 1ms)
- stiray 4y agohttps://go.dev https://go.dev Experienced C developers have switched to it. Actually it gets even better, they are extremely productive in it. Don't trust me, check github. I wonder why. /s
- BenoitP 4y agoWith Loom incoming, Go's only unfair advantage (shared with Erlang) may be gone soon. I guess we'll have the answer in a few years. Will the next WhatsApp be written in Java?
- haspok 4y agoLoom does a small fraction of what the Erlang VM is capable of doing. For one, the Erlang VM has built-in preemptive green thread scheduling, which means it can suspend your green thread at ANY instruction, not just when an IO call is in progress. Loom is a step in the right direction, but Erlang is in its own universe for what it was designed for.
- BenoitP 4y ago> which means it can suspend your green thread at ANY instruction True. Out of curiosity: what's the use case for this? Surely side-effects-out-of-your-system is enough?
- notamy 4y ago> True. Out of curiosity: what's the use case for this? Scheduling is deterministic, which is a VERY useful property to have. See ex. http://erlang.org/pipermail/erlang-questions/2006-December/024588.html http://erlang.org/pipermail/erlang-questions/2006-December/0... about changing scheduler determinism.
- marwis 4y agoThe thread you linked is about the benefits of inducing scheduling non-determinism.
- nocman 4y ago> To use anything else (than JavaSE without heavy deps.) on the server is madness. That's a terribly broad generalization. There are multiple other options that are entirely sane.
- Scarbutt 4y agoWhat other good dynamic runtimes with widespread use like the JVM exist?
- TrueDuality 4y agoRestricting your world view to only programming languages with dynamic runtime environments like the JVM is a major handicap.
- deleted 4y ago[deleted]
- hedora 4y agoLinux, for C/C++/Rust. It also provides memory safety and multiprocessor support.
- lliamander 4y agoBEAM
- DoesntMatter22 4y agoWhen all you have is a hammer... What a ridiculous take, most server apps don't use Java and they are just fine.
- bullen 4y agoThis was true until 2017 when I became a C programmer. They are fine until they need to scale and iterate quickly without downtime.
- DoesntMatter22 4y ago
- badpun 4y agoJava does not (yet) have green threads, which limits the number of connections you can serve per machine. You can go to Scala though (it has them) and still stay on the JVM.
- lliamander 4y agoErlang is not as peformant as Java, but there are plenty of reasons to prefer the former to the latter: - a much better concurrency model, that gets you parallelism for free just by adding cores - no global gc pauses, low-latency - fantastic operational tools (trace debugging, remote shell, etc.) - Erlang/OTP gives you great middleware out of the box, including including queues, pub-sub, service monitoring, database, etc. - Honestly just a more expressive core language. All that said, I don't really have anything against Java. It is a great language for the server, but it is not the only choice.
- haspok 4y agoAll that said, Erlang is a very sharp knife, built for one specific purpose. This is just not true: "a much better concurrency model" If your program is CPU-bound, where real threads are king, then Erlang is a pretty poor solution. Because you cannot have real threads in Erlang, even if you wanted to. Number crunching or string processing are not its forte. Also, most enterprise software does not really benefit from green threads anyway, because the scale they are running on easily handles blocking JDBC and http request calls. Not all companies are google or want to run a telephone switch that handles >million concurrent calls... And finally, if you go Erlang, you get actors, whether you like them or not. You cannot have CSPs, for example, which in many ways are superior to actors. You don't get to choose your concurrency model, it is chosen for you. If your use-case suits this model, great. If not... not so much.
- lliamander 4y agoThere are responses to each of those points, but ultimately you are right that there are tradeoffs. My point was really that Java isn't the only sane server-side language, and that Erlang is an entirely sane option. The one thing I will say is that, when I say Erlang has a better concurrency model, I mean that it is much easier to write correct concurrent code in Erlang than in Java.
- andrekandre 4y ago> CSPs, for example, which in many ways are superior to actors how is csp superior to actors?
- sushisource 4y ago> This combined with the fact that Java doesn't crash Huh? Doesn't crash in what way vs. C? I can still deref a null pointer and blow up. Java's perfectly fine, and I have no idea why you'd write C any more, but if you care about (extreme) performance and not crashing, Rust seems the obvious modern choice here.
- plainnoodles 4y agoOne of the weird things about Java is that there's a big low-latency/high-performance Java community around that stems from Island (now owned by NASDAQ) using Java as the platform/language for their matching engine. Then, talent flow from that team resulted in lots of proprietary trading shops using Java to low-latency trading/order execution.
- SlipperySlope 4y ago
- kaba0 4y agoIf you do that in C, your program may run “just fine” on the surface forever, yet it can silently corrupt all of its data. Java can catch NPEs and handle them appropriately (e.g. a web server might just answer server error 500, but it will continue to run with well-defined semantics). I don’t think the two is comparable. Even Rust will go off the happy path with a single use of unsafe, and there is no sailing back from there, while a Java program can’t crash in a UB-like way.
- icedchai 4y agoI guess you've never hit a JVM bug, then? They happen.
- kaba0 4y agoSure, but only with similar frequencies as an LLVM/compiler frontend bugs. A JVM bug may also be harder to debug, due to all the moving parts, but realistically, it’s always the program’s fault, and those are taken care of. To directly answer you though, no, I haven’t hit a JVM bug that was apparent (so no segfault or anything like that, except when playing with sun.misc.unsafe).
- pca006132 4y agoBut what kind of C program is he comparing against? Single threaded ones? Not heavily optimized ones? Optimized concurrent C programs that use locks rather than lock-free data structures? Or heavily optmized C programs with lock-free data structure? It is unclear to me. Also, wondering how much of that overhead in the C program is due to malloc (can be overcome by memory arena)
- Banana699 4y agoComparing Java with C is about as strawman-ny as it gets, you're literally picking on one of the oldest and dumbest languages in production usage. "The PDP-7 assembler that thinks itself a programming language", in the hilarious words of one wise guy. The problem Java experiences (not 'experienced') is that it isn't the 1990s anymore. People aren't easily hyped, not smart people at least. Programming language research, already way ahead of Java in 1995, moved far ahead some more. The internet and open source and free online education and social media means smart language designer(s) can now begin a baby project and put it on github and wait their luck for a corporation or organization that will support it, and they can wait a decade+ on hobby mode till the luck comes. Java's competition isn't C, I highly doubt it ever was, it's dozens of far superior programming languages that were born after 1995, and some of those that were born before but weren't very populer because internet and open source barely existed in the 1990s and they weren't made by a corporation. Even if you keep overfitting the requirements function time and time again to gradually approach java (by adding "vast libraries" and "performance" to it, although neither of those things are specific to Java), you will eventually reach a very narrow niche with Java and Kotlin squarely in the middle, I know which one I'm going to choose if I'm willing to maintain my sanity and not drown in 'paper-work programming' that is the developing experience with Java. It's as easy as opening a source file in an IDE and naming it with a '.kt' extension rather than '.java', I'm in love with it. Companies use Java extensively ? So it's a COBOL then: Old, everywhere, infrastructure-critical, but an utter failure as a programming language in every way that is not "runs my old program I'm too afraid to re-write". This is forgivable in the case of COBOL because it's a literal proto-language, one of the earliest of the species. It's not forgivable in the case of a language designed when Smalltalk and ML and Haskell were around. The history of Java is the story of a corporation stumbling upon the idea of a VM (1960s stuff) and deciding that it's so good that they need something like this under their name right now, and not giving the slightest shit about the design of the language that sits on top of said VM. And they were right, the idea of a VM is really so fucking good that Java's aweful design was tolerated, until somebody relized running on the JVM no more means writing Java than running on x86 means writing x86 assembly, and wrote the first non-Java JVM language. And because VMs are so fucking beautiful, you get all Java code for free. >doesn't copy everything Java does VM + GC Come on, write those 2 words on any half-decent academic research repository and you will get hits from the fucking 1960s. Java is younger than Lisp, Smalltalk, Self, Haskell, Python and the same age as Ruby. All of those languages do VMs and GCs. Java's hotspot is taken from Self, that's documented stuff. And "Copying" isn't copying if it's a better implementation of the interface, JSON didn't "copy" XML, they reimplemented its interface better.
- a-dub 4y agothere have been a handful of infrastructure projects in java: kafka and cassandra come to mind immediately, but there are certainly others. i think what has always sort of steered me away has been a few things: 1) i've long been interested in snappy, interactive and realtime local and server things. and the jvm can do this stuff, but usually it's better suited for server side use where it can be warmed up appropriately. this may also just be a personal dogma that i need to get over. 2) every language and runtime has its quirks where you have to breakdown the illusions of the language itself and understand the internals to get the best performance, but i feel like java is the worst instance of this, where the tricks that people go through in order to control the gc seem excessive. 3) i like simple and concise programs where i feel like the java ecosystem encourages code sprawl. hello world has so much weird stuff and a serious java project has thousands of small source files where computer aided programming (ie. a proper java ide) is not really optional. i find this not only to be unergonomic, but also challenging for being able to quickly understand what a foreign codebase is doing in a short timeframe. maybe it's different from the perspective of a primary developer on one of these large projects though (and possibly quite pleasant). 4) for some reason, i've always liked feeling closer to the metal. even scripting languages "feel" closer because of the jvm abstraction. this is probably also a personal dogma. > He commented that multi-threaded Java these days far outperforms C, due to the memory management and a garbage collector. people who like java say these sorts of things all the time. i haven't seen a head to head comparison that confirms it though. (although i have not looked). regardless my understanding is that once a jvm is warmed up, it can be quite performant-- and that it has opportunities for live optimization that you don't get in a classic c/c++ runtime. i don't think c/c++ will be going away as long as operating systems are still written in c. a java operating system seems... strange to me. but that said, i think java has proven itself in terms of high performance application server software.
- quadcore 4y agoThe only problem Java has is experienced C programmers don't build servers from scratch with it yet. Please explain. What kind of crazy jack write servers in C? (Real question, trying to learn here)
- varjag 4y agoServers written in C is the status quo here in real world.
- cozzyd 4y agoThe developers of apache httpd, nginx, postgresql, redis, among many others?
- xxs 4y agoyou really dont need redis if you have java. I see zero reasons to offload my datastructures via TCP, instead of have them locally. If need be, replicated them.
- vasilakisfil 4y agoUsually you need redis to scale up horizontally, meaning with multiple servers/processes, and still keep consistency in your data. In general redis is a very useful tool that provides various features, even pub sub.
- quadcore 4y agoRedis has plenty of features your java program hasnt. Starting with reliability :)
- xxs 4y ago>=your= java program hasnt. Wonder why the jab; Personally I'd trust my own code more than redis'
- xmonkee 4y ago
- otabdeveloper4 4y agoI assure you that people writing C++ on the server know how to use lockfree structures and optimized allocators. Using something with a garbage collector when you have access to all that is madness.
- kentonv 4y agoOh, please. I once worked on a Java-based server at Google that had to answer requests with millisecond latency. In order to achieve this, the server had to block garbage collection most of the time. Periodically, each instance of the server would ask the load balancers to stop sending requests to it, so that it could then safely run the garbage collector, and then ask for traffic to return. We likely would not have used Java had we foreseen needing to do this. I believe some time after I left, it was all rewritten in C++. Sadly the garbage collection debate is full of people who want GC to be the answer to everything, and have chosen their arguments and beliefs through confirmation bias to support their desire. Many of these "GC is faster!" arguments come from that, but it just ain't true most of the time. Performant GC is incredibly complex and incredibly complex systems tend to fall over if you don't use them in exactly the right way. Worse, GC is extremely bad at managing resources other than local memory. In complex distributed systems or other software that manages external resources, GC languages tend to be ill-equipped for the job because they lack explicit resource-management tools like RAII. In Java, you sometimes see frameworks where everything has a `dispose()` method and complex systems are built to make sure that `dispose()` method gets called... this is a failure, it should be handled by destructors. GC is generally nice and convenient for application engineering, but a poor fit for systems engineering. The boundaries between the two are admittedly fuzzy.
- luciusdomitius 4y agoSpeaking of this, have you of LMAX Disruptor[0]? You probably have. And yeah, having fine control over the memory allocation and garbage collection in such a high-level language (multi-platform vm!) is akin to building a ship in a bottle. However, in which stack creating multi-level distributed stock exchange with sub-milisecond response times is easy? 0. https://lmax-exchange.github.io/disruptor/ https://lmax-exchange.github.io/disruptor/
- ransom1538 4y agoGoogle should have picked a real language: php. When script is completed all resources are freed, let the OS figure it out. No manual GC drama.
- 4y ago
- tomohawk 4y agoNo doubt, Java GC is a feat of engineering. But it has to be to avoid being swamped by the lack of mechanical sympathy between the language and memory management. Pretty much everything you do generates lots of unnecessary litter, which then must be eventually collected. Except in very narrow circumstances, I've not ever seen Java perform at the level of C or C++, especially when I/O is involved. Java typically needs 2-4x the memory and a lot more cores to do the same job. That's fine if you bought the machine and the machine is big enough, but if you're leasing an EC2, why pay more every hour? These days, my C, C++, and Java days are behind me. We do mostly Go, and couldn't be happier. The GC and language have really good mechanical sympathy, and the bad memories of tuning Java GC are fading. We pay a small tax in terms of CPU and memory over using C, but not remotely like what we saw with Java. And yes, we built prototypes of critical use cases in C just to see how 'bad' Go would be, and were very pleasantly surprised that Go compared very well indeed.
- blub 4y agoReading your message brought flashbacks of 2006, when C and C++ programmers were politely but passionately explaining to Java programmers why the Java ecosystem was a hopeless pile of bloat. I would have thought that in 2022 the failure of Java to conquer any kind of market on the most popular platforms and 2nd most popular or any kind of popular plus the rise of languages like Swift, Go or Rust would have made that point perfectly if not painfully clear. Even in Android, Java’s big success story, both the VM and the language were either outright replaced or made legacy. I suppose it’s a matter of perspective, but I like to think of the server not as Java’s last kingdom, but more as Java’s last refuge before being finally banished. Note that I don’t dislike Java. I’ve used it successfully on Android and it helped us achieve our goals of writing a passably performant application. Neither do I think it’s a bad technology, like many would argue. It is very uninspiring and bureaucratic though…
- kaba0 4y agoI don’t know, other than not having the same hype as “back then”, Java does better than ever. It may not have stuck its original target, but it is bigger than anything has ever been on the server side, with all Fortune 500 companies having heavy investment in the platform.