It seems to be Issue 909 (http://code.google.com/p/go/issues/detail?
id=909) or something similar, which makes Go absolutely unusable for
real world applications on 32bit Linux.
The godoc problem could be solved by auto-killing or running it
"on-demand", so when no request are being handled the process exits
and return memory, this could not be a solution for a high traffic
site but for something like a internnal godoc this should work.
> It seems to be Issue 909 (http://code.google.com/p/go/issues/detail?
> id=909) or something similar, which makes Go absolutely unusable for
> real world applications on 32bit Linux.
Not all real world applications are server side applications. There is
a considerable ammount of applications in Go that are client
applications (text-editor, gocode, games).
--
André Moraes
http://andredevchannel.blogspot.com/
On Thursday, April 5, 2012 10:02:31 AM UTC+2, Erik Unger wrote:
It seems to be Issue 909 ... which makes Go absolutely unusable for
real world applications on 32bit Linux.
For some unknown to me definition of 'absolutely'.
Is this problem related to x86 or does it apply to ARM as well?
And what about the option to disable gc with a compiler switch and doing
the memory management self using delete()? For future versions, of
course.. i've always been sceptical about gc.
Norbert
> The 8g version of the compiler isn't the best choice to long-lived
> process, at least right now, so you don't have much of a choice.
does gcc-go 32b expose the same behaviour ?
(otherwise, it could be a rather good choice)
-s
I think we shouldn't blame the concept of GC because of a issue in one
implementation.
Is this problem related to x86 or does it apply to ARM as well?We are using Go for a real world website (http://startuplive.in) with
real world traffic and the Go process has been crashing every other
hour or so on 32bit Intel Linux.
And what about the option to disable gc with a compiler switch and doing the memory management self using delete()? For future versions, of course.. i've always been sceptical about gc.
You are right about the fact that it is an issue for long-running 32-bit programs. It may be possible to improve the situation by adhering to the following rules throughout your program:- avoid struct types which contain both integer and pointer fields- avoid struct types containing arrays such as [100]byte (replace it with *[100]byte or with []byte)- avoid data structures which form densely interconnected graphs at run-time- avoid deep call chains at run-time- replace pointer identity with value equivalence (this can lead to a more explicit memory management in your program)- if a data structure contains both long-lived and short-lived fields, move the short-lived fields into a separate data structure or into local variables of a function- avoid integer values which may alias at run-time to an address; make sure most integer values are fairly low (such as: below 10000)- if you are using caches to speed up your program, apply the rules mentioned here to redesign the cache. It may also help to use strings instead of structs as map keys.- lower the overall memory consumption of your program- carefully speed up your program (this may lead to a lower memory consumption in certain situations)- call runtime.GC() (at the right moment)
Great!
> We are also running godoc -http behind Apache on another 32 Linux
> machine, and the godoc process is basically killing the whole system
> on a daily basis.
>
> It seems to be Issue 909 (http://code.google.com/p/go/issues/detail?
> id=909) or something similar, which makes Go absolutely unusable for
> real world applications on 32bit Linux.
Very easy to believe. There's no easy software fix here.
The easy hardware fix is to switch to 64-bit.
Russ
Gccgo ought to be better on the margin, because it does not interpret
the entire data section as possibly containing pointers. However, it
does not address the base issue, which is that Go uses a conservative
garbage collector, and more values look like pointers in a 32-bit world.
The only real fix would be to improve the garbage collector's
understanding of which values are pointers and which are something else
(e.g., floating point numbers that happen to look like pointers). And
that is not an easy fix.
Ian
> That is true, André, but Go is advertised as a "systems" PL.
It's not. It used to be, but it's not any more.
A look at recent posts in golang-dev might be enlightening...
Here's a sampling of recent threads about updates to the garbage collector:
Yes, these changes make the GC parallel, so it doesn't pause, but they
do not change the fact that it is a conservative GC.
--dho
1) For most workloads and applications Go works fine on 32bits
2) All recent Atom chips can do 64bits, I'm not sure if old
32-bit-only parts are still sold by Intel, but I doubt they will be
around for much longer.
Let's hope x32 doesn't catch on: http://en.wikipedia.org/wiki/X32_ABI
--
Aram Hăvărneanu
Russ
You should be able to mount the attack in 0 allocations per iteration. Once your assignment is over, if you're still having memory problems, show us the code.
Russ
I've successfully completed the assignment, but a less naive approach
would be interesting. I'll repost when the time times.
Dan
After reading this thread, the issue discussion and a discussion on the
internet, im am now rather confused.
Could someone who understood the problem please summarize it?
- What is actually the problem [1]?
- Which operating systems are affected [2]?
- Does this behaviour affect all long-running 32-bit programs, or only
especially those who allocate a lot of memory?
- Can i somehow detect if my program is slowly running into trouble, e.g
with top or ps, or is it completely hidden inside the go runtime
environment?
- When the program crashes, can it take down other programs as well?
(when the memory is completely exhausted and the os starts killing
processes randomly)?
[1] This thread is about crashing after a while, other discussions
sounded like it was a problem right at the start, when a DLL is loaded
in the middle of the virtual address space...
[2] other discussions were only related to Windows
Thank you for clarification!
Norbert
After reading this thread, the issue discussion and a discussion on the internet, im am now rather confused.It seems to be Issue 909 (http://code.google.com/p/go/issues/detail?
id=909) or something similar,
Could someone who understood the problem please summarize it?
- What is actually the problem [1]?
- Which operating systems are affected [2]?
- Does this behaviour affect all long-running 32-bit programs, or only especially those who allocate a lot of memory?
- Can i somehow detect if my program is slowly running into trouble, e.g with top or ps, or is it completely hidden inside the go runtime environment?
- When the program crashes, can it take down other programs as well? (when the memory is completely exhausted and the os starts killing processes randomly)?
- Does this behaviour affect all long-running 32-bit programs, or only
especially those who allocate a lot of memory?
If you know which code patterns to avoid, the probability of a normal 32-bit Go program running out of memory is close to zero.Below are some concrete examples of code patterns to avoid. An arbitrary binary value is a value which can range from 0 to (1<<32 - 1):type S struct {a, b, c TbinaryData [1000]byte // Replace with *[1000]byte or []byte}
How're the replacements any better than [1000]byte in this case? If
people follow the advice but make([]byte, 1000) dynamically, that may
end up in the heap and they'll get to the same place, right?
--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/plus
http://niemeyer.net/twitter
http://niemeyer.net/blog
-- I'm not absolutely sure of anything.
On Wed, Apr 11, 2012 at 14:23, ⚛ <0xe2.0x...@gmail.com> wrote:How're the replacements any better than [1000]byte in this case? If
> binaryData [1000]byte // Replace with *[1000]byte or []byte
people follow the advice but make([]byte, 1000) dynamically, that may
end up in the heap and they'll get to the same place, right?
On Wed, Apr 11, 2012 at 14:23, ⚛ <0xe2.0x...@gmail.com> wrote:
> binaryData [1000]byte // Replace with *[1000]byte or []byteHow're the replacements any better than [1000]byte in this case?
On Wed, Apr 11, 2012 at 10:35 AM, Gustavo Niemeyer <gus...@niemeyer.net> wrote:On Wed, Apr 11, 2012 at 14:23, ⚛ <0xe2.0x...@gmail.com> wrote:How're the replacements any better than [1000]byte in this case? If
> binaryData [1000]byte // Replace with *[1000]byte or []byte
people follow the advice but make([]byte, 1000) dynamically, that may
end up in the heap and they'll get to the same place, right?Any pointer anywhere in the byte array, no matter how it's allocated, will pin it. Having it as a pointer/reference in the struct keeps the struct from also being pinned.
Sorry, I misunderstood what you meant. I thought you were concerned
about pointers *to* that data causing problems sooner, since the
sample structure doesn't contain visible pointers either and thus
would get FlagNoPointers by itself.
On Wed, Apr 11, 2012 at 14:53, ⚛ <0xe2.0x...@gmail.com> wrote:
> It is better because Go's GC may fail if the struct contains [1000]byte and
> also contains pointer fields.
>
> The GC can handle make([]byte,1000) correctly.Sorry, I misunderstood what you meant. I thought you were concerned
about pointers *to* that data causing problems sooner, since the
sample structure doesn't contain visible pointers either and thus
would get FlagNoPointers by itself.
Pure data in the heap also seems to be handled correctly.
On Wed, Apr 11, 2012 at 14:30, minux <minu...@gmail.com> wrote:Pure data in the heap also seems to be handled correctly.
> Any pure data (i.e. no pointer involved) allocated statically will be
> handled correctly by the current gc toolchain.
This sounds like a good workaround to try once someone has issues, but
I'm sure if we should be providing such recommendations at this point,
as it's hard to really tell what is the cause of such a problem. A
silly edge example: if you have 1GB of contiguously allocated data,
the real issue isn't whether this data has pointers or not, but the
fact that you have a good deal of the address space taken. Then, a
couple of types involved in a conservative leak could hold all of that
data in memory.
If people start having a lot of real issues (this thread doesn't show
that), it's time to fix the implementation IMO, rather than
recommending code bending techniques.
If people start having a lot of real issues
> Greatly simplified:
Thank you very much, and the others, too!
Norbert
I didn't manage to figure out how to do what you're suggesting unless I
don't require that I can return the colliding values (i.e. I can easily
generate collision without allocations if I don't care what they are -
the assignment asked that we give the colliding values).
The linked code <https://gist.github.com/2371244> should generate a
collision with P = ~1023/1024, but in practice during the second run
memory is exhausted (amd64 4GB laptop), so I need to stop the program
and restart (actually the version I used for the assignment does not
have the j loop, and succeeds with P = ~0.5 and I manually ran until
success).
thanks
Dan
On Fri, 2012-04-06 at 19:39 -0400, Russ Cox wrote: