Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix memory leaks #180

Merged
merged 2 commits into from
Mar 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions consumers.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,33 @@ func (subs *consumers) buffer(in chan *Delivery, out chan Delivery) {
}

case out <- *queue[0]:
/*
* https://github.com/rabbitmq/amqp091-go/issues/179
* https://github.com/rabbitmq/amqp091-go/pull/180
*
* Comment from @lars-t-hansen:
*
* Given Go's slice semantics, and barring any information
* available to the compiler that proves that queue is the only
* pointer to the memory it references, the only meaning that
* queue = queue[1:] can have is basically queue += sizeof(queue
* element), ie, it bumps a pointer. Looking at the generated
* code for a simple example (on ARM64 in this case) bears this
* out. So what we're left with is an array that we have a
* pointer into the middle of. When the GC traces this pointer,
* it too does not know whether the array has multiple
* referents, and so its only sensible choice is to find the
* beginning of the array, and if the array is not already
* visited, mark every element in it, including the "dead"
* pointer.
*
* (Depending on the program dynamics, an element may eventually
* be appended to the queue when the queue is at capacity, and
* in this case the live elements are copied into a new array
* and the old array is left to be GC'd eventually, along with
* the dead object. But that can take time.)
*/
queue[0] = nil
queue = queue[1:]
}
}
Expand Down