[#111712] [Ruby master Feature#19322] Support spawning "private" child processes — "kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core" <ruby-core@...>
SXNzdWUgIzE5MzIyIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGtqdHNhbmFrdHNpZGlzIChLSiBUc2Fu
14 messages
2023/01/07
[ruby-core:111830] [Ruby master Feature#19333] Setting (Fiber Local|Thread Local|Fiber Storage) to nil should delete value in order to avoid memory leaks.
From:
"ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>
Date:
2023-01-16 09:53:07 UTC
List:
ruby-core #111830
Issue #19333 has been updated by ioquatix (Samuel Williams).
While the proposed idea is a good move in the right direction, it doesn't handle cases where several (a large number) threads all have the SAME thread local, and that thread local goes out of scope, e.g.
```
name = ":local-#{object_id}
100.times do
Thread.new do
thing = ... something that consumes memory ...
Thread.current.thread_variable_set(name, thing)
# Thread lives for a long time
while job = jobs.pop
job.call
end
end
end
```
Even when `name` is no longer useful for any purpose, all those threads sill still have that thread local set. There is no global way to say "For all threads that have a thread local set for name, please clear it".
In order to do that, we'd need to introduce a `Thread::Local` object which uniquely identifies an association in 0 or more threads, and when that `Thread::Local` instance is GCed, all threads which have it set, have it cleared. This ensures that threads don't leak memory. Consider a work pool that allocates a new `Thread::Local `every now and then... eventually threads will have lots of locals which are potentially no longer useful.
That being said, the other option is just not to encourage people to have long running threads that accumulate cruft over time.
----------------------------------------
Feature #19333: Setting (Fiber Local|Thread Local|Fiber Storage) to nil should delete value in order to avoid memory leaks.
https://bugs.ruby-lang.org/issues/19333#change-101239
* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
As it stands, Fiber Locals, Thread Locals and Fiber Storage have no way of deleting key-value associations.
```ruby
100.times do |i|
name = :"variable-#{i}"
Thread.current[name] = 10
end
```
Because of this, dynamically generated associations can leak over time. This is worse for things like Threads that might be pooled (or maybe an argument against user-space pooling).
In any case, having a way to delete those associations would allow application code to at least delete the associations when they no longer make sense.
I propose that assigning `nil` to "locals" or "storage" should effectively delete them.
e.g.
```ruby
100.times do |i|
name = :"variable-#{i}"
Thread.current[name] = 10
Thread.current[name] = nil # delete association
end
```
A more invasive alternative would be to define new interfaces like `Thread::Local`, `Fiber::Local` and `Fiber::Storage::Local` (or something) which correctly clean up on GC.
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/