This was very interesting, but the ending was a bit abrupt. I was under the impression that there was something more that I was missing under the subscribe banner.
But to the point of the article - are there cases in which manually moving objects around to compact them in a specific area is done with golang? I don't use golang that much, and I'm sure that there are very strong arguments for not compacting the heap post-GC, but I've always wondered how it avoids crashing in the 0.0001% of cases in which heap is defragmented in such a way that there's no way to allocate a new large object
It's because of what's in the second paragraph, which I will paste here for convenience:
"Taking a step back, Go manages memory by allocating objects of the same size class (an object’s size is rounded up to the nearest size class) within a contiguous chunk (or span in Go terminology) of one or more 8KiB pages. Size-segregated allocation is common in some malloc implementations (like tcmalloc, which Go’s allocator descends from)."
(No passive-aggressive snark about reading the article intended; it's a good question and I really am just pasting it for our convenience.)
You can't get the inability to allocate some large object because there's a spray of small objects in its way, because the small objects don't share space with the large object. The large objects live in their own space, and the fragmented small objects can be efficiently utilized later by putting other small things in the empty space later.
In the 64-bit world, you also don't have to worry about how you arrange things in physical RAM so one size doesn't end up impacting another. You can always allocate some suitably-sized new chunk of ram that's incredibly distant in the virtual address space and let the OS map that back to the real RAM. It may do something more clever than that because there is still 32-bit Go and that trick is less freeing in that scenario, but the principle would still hold. You don't get the inability to allocate a large object by small objects because they don't live in the same place. You might still "run out of RAM" before you've quite literally run out of RAM, but you'll get closer.
And ultimately that's a problem shared by a lot of memory allocation schemes, not particular to GC or Go. For a lot of reasons, it's a good idea not to run resource usages right up to 100% if you can avoid it and you can expect across a wide range of resources types to encounter problems and expect to do a lot of careful work to make it possible to hit truly full utilization if you need it for some reason. Beyond computers, even... it's rarely a good idea to plan on 100% utilization of anything be it physical or electronic.
> You can't get the inability to allocate some large object because there's a spray of small objects in its way ... The large objects live in their own space
Assume for the sake of argument that the large object space is for objects >=1MB.
Allocate lots of 1MB objects then free every other one (by address).
Unless you're willing to let the large object space grow without bounds....
There is a theorem that is often stated in operating system courses as "For any possible allocation algorithm, there exist streams of allocation and deallocation requests that defeat the allocator and force it into severe fragmentation.". You can ask your friendly local AI about "Bounds for Some Functions Concerning Dynamic Storage Allocation" by J. M. Robson in the July 1974 Journal of the ACM and some various follow-up papers. For any non-compacting memory management algorithm, including traditional malloc/free, there will always be a way of defeating it and forcing it to fragment.
However, consider that Go has been in production for 14 years now, and one of its bread-and-butter applications is network servers, which will collectively exercise quite a bit of the memory allocation pattern space, including some pathological aspects of it. You should expect to need to do better than that to really throw it for a loop.
While the theorem proves some such sequence exists, there's no guarantee that the sequences will be easy to describe in some sort of English sentence.
I haven’t read the article, but for allocations that large, chances are they get allocated as entire memory pages and the garbage collector returns that memory to the OS.
Also, even if it doesn’t, in a 64-bit address space it takes lots of 1MB objects to make that cause problems (there’s room for over 10¹⁶ of such objects)
One of the drawbacks of relying on the virtual memory subsystem is large page tables, that the machine has to manage on your behalf, and that pollute (or at least occupy) caches. That is another reason why Go, like all other software, benefits significantly if you adjust your Linux boxes to use huge pages, or larger-than-default pages, or ARM contiguous page bits, or whatever other features your platform offers to make virtual address translation more efficient. It is unfortunate that Linux usually comes out of the box with all of these post-286 features disabled.
AFAIK, FreeBSD has been doing transparent superpages for decades (I think it was implemented in 2002 for x86 [1], and 2014 for arm [2]) and I don't know of any real issues with it? (I'm sure you could build a test case where it thrashes and causes trouble) Not sure why Linux wouldn't do the same??
Linux also has support for it but it is up to the distribution, or the user, to enable or disable it. The whole discourse was poisoned years ago when the author of Redis told everyone to disable THP on Linux, but this was caused by Redis being a poor program, not by THP being a poor feature. Unfortunately, even though the Redis project finally removed their document about this, many people still carry this bias.
There was also an issue with Linux about 8 years ago where the THP daemon would start busy-looping searching for pages to amalgamate, wasting loads of CPU time (and I believe freezing the processes it was inspecting), and so people were advising switching off THP for that reason until it was fixed. It hit our large Java processes quite badly.
> The whole discourse was poisoned years ago when the author of Redis told everyone to disable THP on Linux
What's the story behind that? Do normal programs really get affected by this?
Normal programs are most likely using glibc's memory allocator, and I'd be surprised if it was incapable of handling arbitrary page sizes. Only reason why I have to care is I implemented my own memory allocator.
Redis uses jemalloc by default, if I recall correctly, but its hostility to the way systems actually work arises from the way that it forks, then changes one bit on every page in the entire virtual space, which causes a lot of kernel work to support copy-on-write by blowing up huge pages into smaller pages. That's what happens when your program is antagonistic to the way the machine actually works.
> then changes one bit on every page in the entire virtual space
Yeah that sucks. Naively implemented garbage collectors have the same problem: they put the live and mark bits in the object itself which spreads those bits all over the address space. This leads to the garbage collector touching every single page when it scans and writes all of those bits.
The proper solution is to allocate separate bitmap pages. This dramatically improves cache efficiency. Machines always want a structure of arrays.
I've always struggled a bit with the fact that "machines want SoA but readability/clarity/etc is easier with AoS". And wonder if it would be possible for a language to have the code representation be AoS but the implementation transparently be SoA.
That is how everyone decision works, yes. That's why you want limited government. Voting where you can't vote with your money is a very low-quality, delayed signal.
If you assume that decision makers operate entirely in silo from their constituents then yes, that's how this works. Howver if you are operating in the normal mode of democracy where decision makers consult impacted parties through town halls, solicited feedback, subcommittees, etc etc then there are ample opportunities to obtain high-quality, low-latency signals. "Voting with your money" is (IM personal O) a scapegoat for government leaders to avoid doing their due-diligence (not to mention the massive power imbalance that results from people with lots of money 'voting' way more than people with less money).
> If you assume that decision makers operate entirely in silo from their constituents then yes, that's how this works.
Most places have two parties, each of which has a position on several thousand issues. You have two choices: combination A of the several thousand issues, or combination B. You don't get to choose with any more granularity than that.
> not to mention the massive power imbalance that results from people with lots of money 'voting' way more than people with less money
This is a power rectification. If you have two streaming services and one is bad, that bad one will fairly quickly receive far less money as people vote with their wallets. That's not rich people with thousands of accounts "voting" for the winner, it's just a more direct system of people choosing with money.
Politics has a far stronger link to an individual's money swaying decisions than that.
Wouldn't the layoffs be when the price changes are announced then? Isn't going all in on current credit prices mean that you use as many parallel work streams as possible?
It's possible. Ultimately the voters do make the decision, even if they can be swayed. How realistic it might be, I can't say. We certainly need a lot more engagement with the process. There are far too many people ignoring the primaries and then complaining about their lack of choice in the general.
I don't believe donations or corporate backing had anything to do with Trump, for example, winning. Trump won because he genuinely appeals to the average voting American. American voters are willingly choosing to support these politicians and all of the consequences that entails.
For the president election, maybe, but without corporate backing of the GOP he would have to face an adversarial congress. Or at least, that’s the hope
It's about app-ifying the desktop. Instead of opening a browser, then remembering that you have a bookmark and clicking it or googling the site you are looking for, the idea is to have a step less and just click something on your desktop or taskbar (like on a mobile device)
In my local(?) community (like in my city, not my industry) there is a saying "if you had to ask for relationship advice, then you probably should break up".
There is some rationale to that. People tend to hold onto relationships that don't lead anywhere in fear of "losing" what they "already have". It's probably a comfort zone thing. So if one is desperate enough to ask random strangers online about a relationship, it's usually biased towards some unresolvable issue that would have the parties better of if they break up.
> So if one is desperate enough to ask random strangers online about a relationship
I'd me more inclined to ask random strangers on the internet than close friends...
That said, when me and my SO had a difficult time we went to a professional. For us it helped a lot. Though as the counselor said, we were one of the few couples which came early enough. Usually she saw couples well past the point of no return.
So yeah, if you don't ask in time, you will probably be breaking up anyway.
Most people engage in romantic relationships because they'd like to find someone to marry and settle down with. Nothing but respect for the people who've thought it through and decided that's not for them, but what's much more common is failing to think it through or worrying it would be awkward/scary/"cringe" to take their relationship goals seriously.
That's what people are pointing to when they talk about relationships not "leading anywhere". If you want to be married in 5-10 years, and you're 2 years into an OK relationship with someone you don't want to marry, it's going to suck to break up with them but you have to do it anyway.
Maybe I'm too much of a hopeless romantic, but from my perspective and experience, when someone is good for you, you'll fight for that relationship regardless of what others say, and conversely when you're in a situation where your actively asking and willing to consider "leave" from someone who isn't a very close friend or a therapist as applicable, then it's likely you're looking for external validation for what you've already essentially decided.
Wait, other people don’t make decision trees and mind maps and pro/con lists and consult chatbots before making decisions? Are they just flying through life by the seat of their pants? That doesn’t seem like a very solid framework for achieving desired outcomes.
But to the point of the article - are there cases in which manually moving objects around to compact them in a specific area is done with golang? I don't use golang that much, and I'm sure that there are very strong arguments for not compacting the heap post-GC, but I've always wondered how it avoids crashing in the 0.0001% of cases in which heap is defragmented in such a way that there's no way to allocate a new large object
reply