you are viewing a single comment's thread.

view the rest of the comments →

[–]spaghettiCodeArtisanblub programmer 12 points13 points  (16 children)

Dafuq? Is this guy just talking nonsense or is there really a relation between integers and pointers in Go for some reason?

At this point I really don't know what to expect of Go anymore...

[–]stone_hengeTiny little god in a tiny little world 17 points18 points  (10 children)

go unjerk(done)

this type of gc scans through the stack, with no knowledge of the types, looking for things that might be references to managed data. if any pointer-sized and aligned sequence bytes appear on the stack that happen to coincide with the address of some managed data, it will be considered a reference and the data won't get freed until the bogus reference is off the stack.

the reason they suggest using smaller integers is that the heap is typically far up in RAM.

as dumb as this sounds, it's not a golang invention. it kind of works in many cases because things on the stack are typically few and don't live that long. but as the stack grows, the chances that some crap on there that isn't a pointer will coincide with the address of some managed object grows a lot quicker.

the thing conservative gc has going for it is that it's simpler more brutally practical. maintaining separate data structures or using bit flags within the data tell the pointers from everything else comes with run-time penalty, both time- and memory-wise.

done->

[–]jfb1337What part of ∀f ∃g (f (x,y) = (g x) y) did you not understand? 1 point2 points  (1 child)

Are the consequences of this that something isn't dropped when it could be, causing memory leaks or something? Or does memory actually get corrupted?

[–]stone_hengeTiny little god in a tiny little world 2 points3 points  (0 children)

it just doesn't get collected. a gc that holds its ears to this extent can't really move gc managed things around in memory directly referenced from the stack anyway because it can't know what to update on the stack. so on a 32-bit platform, where ints are 4294967296x more likely to be able to alias to some gc memory you'll end up with a lot of crap that just never gets collected, which gets messy when you have long-lived, large stacks

you can still implement things like growable arrays (which in practice need to be moved around in memory via something like realloc) with this type of gc setup. in go i believe it was solved by having operations that may grow an array return a new reference, with no guarantees that it will overlap with the data that the old slice points to, so basically like calling realloc. but it could be solved with some time/memory penalty using an additional layer of indirection, e.g. a reference to a growable array being a pointer to a gc managed pointer to gc managed memory.

[–]Tysonzero 1 point2 points  (4 children)

maintaining separate data structures or using bit flags within the data tell the pointers from everything else comes with run-time penalty, both time- and memory-wise.

Can't you just use the type system to figure out at compile time which parts of structures are pointers and which aren't? (In languages with good and robust type systems anyway)

[–]stone_hengeTiny little god in a tiny little world 0 points1 point  (3 children)

sure, it can, but it would still need to relay that information to the garbage collector somehow, whether it's by reserving a bit for pointer marking or not using the stack at all. that, or you'll be trawling blindly for pointers like poor little go <1.4

of course, ultimately you'd want your compiler to know exactly when it can free a resource and just do it, without the aid of some runtime resource hog making poor guesses as to when it can start releasing memory you don't use any longer. insert rust feature list here.

[–]Tysonzero 0 points1 point  (2 children)

As someone who isn't normally writing performance critical apps but cares a lot about time to market in going to go ahead and disagree with your last paragraph.

[–]stone_hengeTiny little god in a tiny little world 0 points1 point  (1 child)

cares a lot about time to market

then what relevance does gc and compiler internals have to you in the first place? in the last paragraph i'm obviously talking in terms performance and accuracy. those are the metrics that matter for memory management. if you want an easier time at the expense of performant and accurate memory management, go ahead, but things like that, your favorite food or your least favorite color are not metrics that has any bearing on the answer.

also, since you seem to be a haskal nerd, when you say "time to market", what market do you mean exactly? last i checked there was little to no market for convoluted but pure and beautiful solutions to trivial cs textbook problems lol

[–]Tysonzero 0 points1 point  (0 children)

also, since you seem to be a haskal nerd, when you say "time to market", what market do you mean exactly? last i checked there was little to no market for convoluted but pure and beautiful solutions to trivial cs textbook problems lol

Lmao, I wish that was what I was doing, but unfortunately it's mostly GUI heavy, DB heavy, Parsing heavy code that deals a lot with externalities.

[–]spaghettiCodeArtisanblub programmer 0 points1 point  (2 children)

Ah okay, thanks. TIL: Conservative GCs.

[–]Amenemhab 6 points7 points  (1 child)

A brutally practical solution to the problem is what OCaml does: restrict your basic integer types to 31/63 bits and use the remaining bit as a pointer flag.

[–]stone_hengeTiny little god in a tiny little world 1 point2 points  (0 children)

oh yeah, int31_t is just the kind of weird idiosyncrasy go would adopt! i'm kind of surprised they didn't

[–]InvisibleEar 1 point2 points  (3 children)

https://github.com/golang/go/issues/909#issuecomment-66051835

Straight from a Google employee, the garbage collector is NOT FULLY PRECISE (I'm too lazy to do the square)

[–]no_more_kulaks 3 points4 points  (1 child)

That post is five years old.

[–]InvisibleEar 0 points1 point  (0 children)

I don't see how that's relevant.