Last active
September 17, 2016 21:23
-
-
Save monorkin/b25a7e4c4b2456d4887d75a25226e64a to your computer and use it in GitHub Desktop.
This file contains 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
# Example 1 | |
module Logger | |
extend self | |
attr_accessor :output, :log_actions | |
def log(&event) | |
self.log_actions ||= [] | |
self.log_actions << event | |
end | |
def play | |
output = [] | |
log_actions.each { |e| e.call(output) } | |
puts output.join("\n") | |
end | |
end | |
class Thing | |
def initialize(id) | |
Logger.log { |output| output << "created thing #{id}" } | |
end | |
end | |
def do_something | |
1000.times { |i| Thing.new(i) } | |
end | |
do_something | |
GC.start | |
Logger.play | |
Logger.log_actions = nil | |
GC.start | |
puts ObjectSpace.each_object(Thing).count # returns 1000 | |
# because each block stores a Thing object in it's closure | |
# and there are a 1000 blocks in log_actions | |
# Example 2 | |
module Logger | |
extend self | |
attr_accessor :output | |
def log(&event) | |
self.output ||= [] | |
event.call(output) | |
end | |
def play | |
puts output.join("\n") | |
end | |
end | |
class Thing | |
def initialize(id) | |
Logger.log { |output| output << "created thing #{id}" } | |
end | |
end | |
def do_something | |
1000.times { |i| Thing.new(i) } | |
end | |
do_something | |
GC.start | |
Logger.play | |
puts ObjectSpace.each_object(Thing).count # returns 0 | |
# as expected | |
# Example 3 | |
module Logger | |
extend self | |
attr_accessor :output, :log_actions | |
def log(&event) | |
self.log_actions ||= [] | |
self.log_actions << event | |
end | |
def play | |
output = [] | |
log_actions.each { |e| e.call(output) } | |
puts output.join("\n") | |
end | |
end | |
class Thing | |
def initialize(id) | |
Logger.log { |output| output << "created thing #{id}" } | |
end | |
end | |
def do_something | |
1000.times { |i| Thing.new(i) } | |
end | |
do_something | |
GC.start | |
Logger.play | |
Logger.log_actions = nil | |
GC.start | |
puts ObjectSpace.each_object(Thing).count # still returns 1000 | |
# Known memory leak - explaned in the first example | |
# but why are they kept in memory? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment