Earlier quoted context omitted.
It's a tradeoff. Go programs are extremely slow at starting up for example.
That doesn't matter for anything other then CLIs.
Reverting the incremental GC in Python 3.14 and 3.15
111–120 of 134 posts
Re: Reverting the incremental GC in Python 3.14 and 3.15
#112Re: Reverting the incremental GC in Python 3.14 and 3.15
#113Earlier quoted context omitted.
Java lost almost all those knobs a while ago (I mean they're there, but you're better off relying on the defaults). The modern GCs have one or at most two knobs remaining, and even that will become unnecessary next year. As to predictablity, you get maximal pause time of well under 1ms for heaps up to 16TB.
As far as I know, java has 7 GC implementations, none of which are perfect, all of which have drawbacks Lately, they seems to work with CRIU, various heuristics, multi-stage in-process bytecode compilation .. Java is a mess, they are working hard to avoid fixing their issue (that nobody else have, so fixes are available)
Not sure what you mean by this, as this has nothing to do with GC, and Java has had a multi-tier optimising compiler for 15 years now.
> that nobody else have, so fixes are available
Go has much worse problems with GC than Java does these days, and nobody else is able to achieve similar performance in large programs with heavy workloads. So everyone else lives with less sophisticated compilers and memory management simply by accepting worse performance.
Re: Reverting the incremental GC in Python 3.14 and 3.15
#114Earlier quoted context omitted.
> As far as I know, java has 7 GC implementations, none of which are perfect, all of which have drawbacks Compared to Python's, all of them are beyond perfect. And 99.9% of the time you don't even need to use anything but the default.
> Compared to Python's, all of them are beyond perfect. I somehow understand the situation less after reading this. Is Python's GC bad , or are there cyclic reference issues? Is it possible to detect cyclic references perfectly? What does beyond perfect mean? If we have 7 and 0.1% of the time you need one of the 6 that is non-default, how do we choose? Is the understated version of "Compared to Python's, all of them…
Yes. The GCs in Java, .NET, V8, and Go do it.
> If we have 7 and 0.1% of the time you need one of the 6 that is non-default, how do we choose?
Java's GC are optimised for different workloads and environments, and when the choice matters, they're easy to choose among:
1. Parallel GC: Maximal throughput when latency doesn't matter (batch processing).
2. Serial GC: Very small machines.
3. ZGC: low latency (4. G1 (the current default): A balanced mix of throughput and latency.
These are all the standard GCs (the seven you mentioned include a GC similar to Go's that was removed years ago, an "no op" GC for benchmarking hidden behind a development flag, and alternative implementations by different companies to some of the ones above).
It's possible that either Serial or Parallel will be removed when G1 is able to fully replace them.
Now, why do users need options? Because Java runs most of the world's finance, manufacturing, shipping and logistics, telecommunication, travel, healthcare, retail, defence, and government. We're talking large, complex software that handles huge workloads, and the needs vary. What works well enough for a CLI dev tool or a simple website is often not good enough to handle the world's credit card transaction processing or mobile phone networks.
> If not, what about Python's impl makes it so lackluster to any of 7 of Java's?
Java's GCs are moving collectors, which offer advantages not just compared to Python's GC but to all memory management strategies. Memory management (even in C) imposes a CPU/RAM tradeoff. Moving collectors (used in Java, .NET, and V8) give you a knob for controlling the tradeoff, i.e. they're able to convert RAM to CPU (i.e. use RAM chips as a hardware accelerator) and vice-versa.
Re: Reverting the incremental GC in Python 3.14 and 3.15
#115Earlier quoted context omitted.
> Is Python's GC bad, or are there cyclic reference issues? Both can be true. The first can even be wholly or partly due to the second. On addition, the way it does it via RC causes fragmentation, poor locality for caches, and general slowness for mass allocations. And it's one-size-fits-all. Java has a much larger selection to pick to finetune specific use cases, which each being far greater for that use case. And t…
Are you not confusing GC (freeing memory) with the memory allocator ? Memory allocator: tcmalloc, jemalloc, they are concerned with fetching (and releasing) pages of memory from the OS and allocating objects for the program GC is only responsible for saying to the memory allocator "this object is no longer used" (please stay focused on java)
No, you're missing the fact that the allocation of memory and the GC go hand in hand, because you need it so for optimizations. They are designed together to cooperate in modern runtimes.
Re: Reverting the incremental GC in Python 3.14 and 3.15
#116Earlier quoted context omitted.
All Python versions are LTS if you consider 5-year a good measure. https://devguide.python.org/versions/
If all releases are LTS, then none are. Part of the point GP was making is that when some releases have a very short maintenance window, then changes that are terrible in them don't need to be reverted (since the maintenance window will close soon anyways).
Re: Reverting the incremental GC in Python 3.14 and 3.15
#117Earlier quoted context omitted.
Why are people still building systems on top of a language that continually undergoes fundamental changes nearly 40 years after release? Is this not the strongest indication that this language is not well designed, it is unstable, and encounters many issues that flat out don't exist in other high level languages?
What language that is actually used 40 years after release isn't undergoing big, fundamental changes? Java? Nope, you're getting a fundamental change in Valhalla C++? Nope, new language edition every few years with fundamental changes C? C23 has a number of fairly fundamental changes, expect more in the next language revision I think your sense of causality is backwards here. These languages are getting fundamental c…
But most such languages handle much better the compatibility with legacy applications.
Python is the main culprit in most cases when I see conflicts between various software packages that insist to use only a specific version of their dependencies. This is why I have to keep installed many versions of Python, and the Linux distribution that I use must take care to prevent interference between those Python versions.
Re: Reverting the incremental GC in Python 3.14 and 3.15
#118Earlier quoted context omitted.
With a similar amount of experience with both languages I found Go much easier to read. I've always been a bit miffed why Python is seen as easy to read for experienced developers. I get the syntax is good for short code or people with little experience but my experience is those readability benefits went away quickly with time or complexity.
Any language that uses error codes instead of exceptions is a non-starter for me. Produces code that craps all over the happy path. Python has a different problem: it is slow as f---. I did a micro benchmark comparison against 5 other languages in preparation for my python replacement language. Outside of dictionary lookups, it is 50-600 times slower than C depending on the workload. Go, Rust etc are fine. They land…
Many early programming languages handled errors by providing multiple return addresses to functions.
Thus a function returned to the place of invocation in the normal case, otherwise it returned to one of the error handlers that were grouped at the end of the function that invoked it, away from the happy path.
This was more efficient than the modern way of returning an error code, as it eliminated the superfluous testing of the error code and the expensive conditional jump based on the result of the testing.
Moreover, in my opinion in the majority of the cases maximum information about an error is inside the function that has invoked the function where the error happened and neither in an exception handler several levels above it, nor inside the invoked function, so the place where the error handlers had to be put in this old method is actually optimal for meaningful error messages.
From the point of view of the source text, this old error handling method is equivalent with using exceptions with the constraint of placing the exception handlers in the function that has invoked the function that generates the exception. This limitation enabled a more efficient implementation than for exceptions where the handler can be placed anywhere above the invoked function and a complex stack unwinding may be necessary.
Re: Reverting the incremental GC in Python 3.14 and 3.15
#119One of heuristics to find memory leaks can be stated as follows: if you instantiate any HTTP or connection objects inside the request handler, it's likely that you've made a mistake.
Re: Reverting the incremental GC in Python 3.14 and 3.15
#120Earlier quoted context omitted.
> Is Python's GC bad, or are there cyclic reference issues? Both can be true. The first can even be wholly or partly due to the second. On addition, the way it does it via RC causes fragmentation, poor locality for caches, and general slowness for mass allocations. And it's one-size-fits-all. Java has a much larger selection to pick to finetune specific use cases, which each being far greater for that use case. And t…
Are you not confusing GC (freeing memory) with the memory allocator ? Memory allocator: tcmalloc, jemalloc, they are concerned with fetching (and releasing) pages of memory from the OS and allocating objects for the program GC is only responsible for saying to the memory allocator "this object is no longer used" (please stay focused on java)
This is simply not true. Not only are Java's GCs responsible for allocation (which they do simply by bumping a pointer, similar to stack allocation), unlike Python's refcounting collector or Go's nonmoving tracing collector, they have no free operation of any kind and never free objects. Moving collectors don't even know when an object is freed. The way they work is that they compact the live objects, and because the dead objects are invisible to them, they happen to write over them when compacting the live ones. Refcounting collectors and nonmoving tracing collectors do use a free-list-based allocator that they use for allocation and deallocation, but moving collectors work completely differently.
Moving collectors can be so efficient that in the eighties, there was a famous paper about them called "Garbage Collection Can Be Faster Than Stack Allocation" [1] showing that the cost of managing an object's lifetime with a moving collector can, in principle, be less than a single machine instruction. That's why the cost of heap memory management in Java (and other runtimes that employ moving collectors) cannot be compared to the cost of memory management in languages using free lists, be it C or Python. Their operation is just too different (e.g. in Java, assigning a value to an object field or setting an array cell could sometimes be more expensive than allocating a brand new object/array).