pron
Joined 15 years ago
Joined 15 years ago
No, that's not the conclusion. If using models costs you, say, $10 an hour, and a GB of RAM costs you, say, $0.0001 an hour, then clearly you shouldn't spend your time on reducing the insignificant cost if you want your work to deliver the most value to users.
But again, "less RAM" is more or less meaningful whether you're reducing the RAM usage from, say, 5% to 1% or from 80% to 40%. The latter is more valuable even though it's a lower relative reduction. That's because what the users care about is in what conditions they reach 100% of either CPU or RAM, and the second 2x reduction, therefore, offers more value than the first 5x one. This is similar to how a 10% discount on a car offers far more value than a 99% discount on a pack of chewing gum. This is still the case if you're buying 100 packs, but maybe not 10,000, and the same goes for software: it may also matter how many copies of the app the user is expected to run concurrently. The point is that you can't assign a value to a 10x reduction if that's all you know.
> I'm entertaining this nonsense because I want to clarify, that I use a 20 year old web gui and it consistently eats 8 gigs of ram in Webkit because it uses CSS to update the forms.
And I'm entertaining this nonsense because you're clearly not a very experienced engineer and you may learn something. In the ninetees, when nearly all GUI apps were written in C or C++, we had plenty of examples where a C++ GUI app consumed 50% RAM. That doesn't mean that C++ is worthless, only that some software has serious resource bugs, and it sounds like that web page you're referring to is a case of that. Most web-based GUI apps today do not consume a higher portion of RAM than their C++ counterparts did 30 years ago. Today's browser-based MS Word consumes less (relative) RAM than the C++ version did in 1998, and it certainly has a far smaller negative impact on concurrently using other apps on the machine.
And, of course, there are buggy/leaky programs now just as there were then. It's silly to say that the existence of such programs means that the approach is bad, because that would apply to any sufficiently-popular language or toolkit.
Anyway, our job is to offer the most value to our users, and reducing RAM consumption by 3% or even 5% (of available RAM) is usually not where you'd find much value.
Because that's not what I said. My point was more that a "1000% memory inflation" is not a meaningful cost metric to begin with (to use just one toy example, perhaps you'd agree that going from 10% RAM to 100% has a very different impact than going from 1% to 10%, even though both are a "1000% inflation").
Memory (at least on a personal computer) is not rented by the hour on a per-MB basis; you buy it in bulk. What matters isn't how much memory you could have used but what you'd use the "saved" memory for. Also, when you buy a resource like RAM or CPU as a package, nominal values matter less than under what conditions one of these would reach 100% and your experience may be degraded.
For example, if you have 16GB of RAM and you only ever run one program at a time, it doesn't matter to you at all if it uses 3GB or 3MB: you've paid for 16 and the total savings of the 3MB app are zero and in this hypothetical case, there's no tradeoff at all. Now, the average user on the average hardware doesn't use only one GUI app at a time, but they're also not using 200. The only relevant question pertaining to waste is what is the value of 3% memory to your users (integrated over all of them)? In many situations (again, not all), the answer is not much. (And BTW, some developers seem to care about 3% memory more than they do about 3% CPU, even though CPU is much more expensive).
When it comes to agent harnesses, the analysis is clearer. On the one hand, people using coding agents are more likely than others to put even a little extra free RAM to some good use, but on the other hand, the cost of using the models themselves is so high that it makes the cost of RAM for the GUI negligible.
Saying that a number going up by 1000% is bad is not good engineering. Good engineering requires thinking about the actual value and cost of that number. It varies over time, over app type, over different types of users, and over different kinds of deployments (i.e. how RAM is packaged and paid for).
The first use case is the very common one (for Java) where developers control deployment (internal deployment). The last basic building block, caching machine code, will be released next year in JDK 28, and then the feature is likely to evolve to better support other use cases, such as external deployment.
[1]: More precisely, the work they need to do doesn't scale linearly with the allocation rate as is the case with non-moving approaches. Of course, arenas are sort of degenerate moving collectors, so they also display the same effect, but they can't always be used.
The way this works is that you allocate in the young generation with a pointer bump, and to free memory you compact (move) the surviving objects, which make up a small minority, a few times and then promote (move) them to the old generation (where you either manage memory with the same technique or a different one). And so the total amount of moving is not high (objects either never move or rarely move), and what you end up with is essentially two heaps, one where the allocation rate may be high but you can completely negate all the extra work by increasing the size of that heap, and one where the allocation rate is low. This ability to, optionally, not double the amount of work when the allocation rate doubles is what gives moving collectors their efficiency (and that you can bump-allocate in virtually all cases).
Of course, it's possible to come up with programs where objects do move a lot (or there's some other common work), e.g. programs that don't exhibit the behaviour of the generational hypothesis, but the point is that in a very large class of programs, this technique is hard to compete with.
2. Heap allocation is a very common cause of serious performance problems in low-level programs because malloc/free overhead is so high. Some languages have a moving GC to reduce the high overhead of heap allocation, but low-level languages typically can't use that optimisation, so you have to resort to arenas (which offer a similar optimisation to that of moving collectors). This isn't always faster than malloc/free, but it usually is, and if you want malloc/free you can pick that.
Anyway, I wouldn't say that the default in Zig is to use an arena, rather it's to give you the control that's the whole purpose of low-level languages.
It's not those features, though! Obviously, a hoarder has everything, so anything you buy is something he has. We are adopting a small portion of the features that feature-rich languages have, which is exactly the difference between a more feature-rich language and a more minimal one.
> ...aaand there it is again. "The lesser languages".
Again? I haven't said "the lesser language" once, although you've now said it a few times as if quoting me. You're arguing with things I haven't said and then misquote me to completely change the meaning of what I actually wrote.
No one, on the Java team or outside it, considers Lisp, Smalltalk, and ML - the languages that inspired Java - "lesser" languages. They are, however, all less successful languages as a matter of fact. It is because they are not lesser but they are less successful that we selectively adopt a portion of their ideas but do not adopt their strategy.
It's not about snobbery, but basic business strategy. Suggesting that it's good business for a product to adopt the strategy of some competitor product doesn't make much sense when that other product is doing worse than your own. I mean, maybe it could be interesting if there were some other key element to the plan, but not on its own.
Almost every single feature in Java was inspired by (or sometimes copied from) a feature in a less successful language (although not always less successful at the time the feature was adopted), but Gosling was always very clear about copying good ideas into a product with a very different strategy (he thought it was the strategy that hindered those other products, not their ideas).
> When Java ends up adopting those features, suddenly it's "we accommodate a non-minority number of developers" and "we've been thinking about this since before Java was released".
No, we've also been thinking about features that may well probably never make it. I'm not even sure what you're trying to say, but you should know that anyone who works in language design has been familiar with type inference, generics, typed lambdas, pattern matching, and algebraic data types at least since the late eighties because ML has been the biggest single influence on language designers and other PL fans in the past couple of decades (ML was released in the early seventies, but it didn't become so influential right away).
> I'm glad it seems you're in the minority seeing how Java has picked up its development pace.
Java has picked up its development pace compared to the time we were involuntarily stagnant due to declining investment from our corporate overlords. As always, most of the development is in the runtime, as that has always been our strategy, and we all think it's a good one. I'm very happy that we can do more now than we could fifteen years ago, but the Java language won't become a (relatively) feature-rich language, even though it will continue to add features.
I said "strategy" not "feature". That adopting a feature that a less successful language had invented or adopted is not the same as adopting the strategy of a less successful language was precisely my point about buying a sofa not being the same as "catching up" to a hoarder.
I said "we shouldn't be a hoarder", not "we shouldn't get a sofa".
> Now you're suddenly saying "we're aware that a non-tiny minority of developers prefer richer languages, and so we accommodate them, too" and "oh yes, we've been thinking of these features since 1991".
But Java started adopting ML features over twenty years ago. Where do you think we got generics from? The discussion about lambdas and generics between Gosling and Joy, even predating Java's release are Java lore (https://archive.computerhistory.org/resources/access/text/20...).
> Than whatever your ever-changing definition is. Java, thankfully, is no longer a small/smaller language, and is rapidly adopting actual useful features, including those from lesser products.
My definition isn't ever-changing, it's just relative. Being a relatively small language means, at the same time, not adopting the strategy of richer languages and adding select features but at a slower pace. This was Gosling's "a wolf in sheep's clothing" strategy since the very start: a very innovative, fast-moving runtime (where most of the benefits to the software's end user are hidden) wrapped in a non-threatening, conservative language. Conservative doesn't mean frozen and relatively small doesn't mean never-growing, but they do mean not adopting relatively rich fast-changing language strategy either. Our strategy has worked well for us, and yes, I still think it's silly to suggest we should change it because languages that aren't doing as well have a different strategy.
Even Java's GC and JIT came from Lisp and Smalltalk, but not the strategy (which was Gosling's point that these helpful features were part of thretening products).
> but anyone who cares about new features like pattern matching was already on Kotlin a long time ago.
First, that doesn't mean it's not a minority of people. And by the way, we don't base our decision on which language feature to include on the number of people who are already asking for a feature (which is always a small minority) but on the number of people we believe will be significantly helped by a feature once they learn about it. I.e. it is perfectly possible that 100% of the people who wanted pattern matching before we added it had left for Kotlin or Scala and at the same time that number amounts to only 10% of the people who enjoy the feature and benefit from it in Java. That many mainstream languages add a feature is only a signal to us that the median developer is ready for it if we decide it's a good feature to add. I've been using pattern matching since the late nineties when I first learnt ML and a bit of Haskell (Haskell was the language of the future back then), but if I were a language designer back then, I'm not sure I would have thought that it's a feature a mainstream language should have prioritised in 1998.
Second, we don't have usage telemetry in the JDK so we don't get a full picture, and instead we rely on the usual sources for this kind of information: meeting with large customers and analyst reports. If you have access to more comprehensive statistical data, then I would be interested in seeing it, but it's a well-known phenomenon that people are usually only directly exposed to information about their own circles and don't have industry-wide data. The Java ecosystem is huge, and like the situation with the software industry in general and enterprise software in particular, most Java software isn't even written by software companies.
BTW, SGCL is a non-moving mark-and-sweep collector and non-moving collectors are no more similar to moving collectors than malloc/free is similar to moving collectors. Garbage collection contains different classes of algorithms with different goals that are so different from one another that it's almost pointless to put them in the same category. Java uses moving collectors because it's the class of algorithms designed to reduce the throughput overhead of all non-moving approaches (from manual malloc/free, through automatic RAII and refcounting GC, through tracing mark-and-sweep collectors like SGCL or Go's GC). In important ways, all non-moving approaches are more similar to each other (regardless of the use of a GC) than any of them are to moving approaches. (Java did have a concurrent mark-and-sweep collector at one time, but we removed it some years ago)
Working on OpenJDK at Oracle