Last active
May 25, 2018 07:36
-
-
Save serradura/5b72c80eb9c4b11d61bd92926896bff0 to your computer and use it in GitHub Desktop.
Ruby closure memory leak labs (Based on https://practicingruby.com/articles/closures-are-complicated)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module LazyLogger | |
extend self | |
attr_accessor :output | |
def log(&callback) | |
@log_actions ||= [] | |
@log_actions << callback | |
end | |
def flush | |
@log_actions.each { |e| e.call(output) } | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class User | |
def initialize(id) | |
@id = id | |
LazyLogger.log { |out| out << "Created User with ID #{id}" } | |
end | |
end | |
LazyLogger.output = "" | |
1000.times { |i| User.new(i) } | |
GC.start | |
p ObjectSpace.each_object(User).count # => 1000 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class User | |
Log = -> id do | |
-> out { out << "Created User with ID #{id}" } | |
end | |
def initialize(id) | |
@id = id | |
LazyLogger.log &Log.curry[id] | |
end | |
end | |
LazyLogger.output = "" | |
1000.times { |i| User.new(i) } | |
GC.start | |
p ObjectSpace.each_object(User).count # => 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Module | |
def private_const(name, value) | |
const_set(name, value) | |
private_constant(name) | |
end | |
end | |
class User | |
private_const :Log, -> (id, out) do | |
out << "Created User with ID #{id}" | |
end | |
def initialize(id) | |
@id = id | |
LazyLogger.log &Log.curry[id] | |
end | |
end | |
LazyLogger.output = "" | |
1000.times { |i| User.new(i) } | |
GC.start | |
p ObjectSpace.each_object(User).count # => 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Logger | |
extend self | |
attr_accessor :output | |
def log(msg) | |
output << "#{msg}\n" | |
end | |
end | |
class User | |
def initialize(id) | |
@id = id | |
Logger.log("Created User with ID #{id}") | |
end | |
end | |
Logger.output = "" | |
1000.times { |i| User.new(i) } | |
GC.start | |
p ObjectSpace.each_object(User).count #=> 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: Other programming languages have similar issues with closures. e.g:
Javascript: https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/
C#: http://www.davejsaunders.com/2017/05/06/memory-leak-lambdas.html