Hi Yota,

I don't disagree there's value in understanding how Go handles the
scenario. What I'm not certain of is the potential tradeoffs when
optimising for an uncommon edge case.

The loop you've created is very tight and would be unusual to find in a
typical application. The allocator is moving faster than GC could ever hope
to keep up. Given it's an endless loop without any work I think there would
be a tradeoff of performance to guard against something that will only
exist in micro-benchmarks and/or invalid code.

I would expect that if you introduce some "work" the memory leak would go
away.

Kind regards,
Nathan

On Fri, 3 Mar 2017 at 01:10 Yota Toyama <ravi...@gmail.com> wrote:

Volker,

I don't know if the term "memory leak" is misuse.
But, the 1st version's memory usage is constant but the 2nd version's one
grows over time as if nothing is garbage-collected.


Yota


On Friday, March 3, 2017 at 2:38:08 AM UTC+9, Volker Dobler wrote:

Am Donnerstag, 2. März 2017 17:15:05 UTC+1 schrieb Yota Toyama:

Hi, all.

I'm trying to understand argument liveness in Go 1.8.
As preparation for it, I wrote 2 programs which iterate over infinite lists.
At first, I thought both can be run forever without any memory leak.
However, the result was that one could and the other couldn't.

Their main difference is the way to iterate lists.

l := *NewList(42, nil)

for {
  l = *l.Rest() // Cause no memory leak :)
}

vs

l := NewList(42, nil)

for {
  l = l.Rest() // Cause memory leak!!!
}

The repository is here <https://github.com/raviqqe/argument-liveness.go>.
I wanna understand why the latter causes memory leak and what is going on
in my programs at low level.
Any ideas?



What makes you say that one version causes a memory leak?

The first version produces much less garbage (well, basically none):
l is a ListValue and the freshly created "list rest" is assigned to it,
basically just overwriting the memory location of l with the same
value.

The second version produces an endless linked list where only the
last list element is reachable from your code as this is the only value
you have a pointer to.

So the second produces tremendous amounts of  garbage but this
garbage is collectable. Running it shows no problem when tracing GC
at least not with Go 1.8.

So the main difference is: The first code does not produce an "endless
list" it just operates on one List value while the second code really
constructs an ever increasing linked list if List values where only the
tail is reachable/uncollectable.

How did you determine the second version "leaks"?

V

-- 
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

-- 
- from my thumbs to your eyes

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to