Permalink
Browse files

Address memory leaks.

- set each example's instance of the group to nil after processing.

This dereferences the example group instance which contains all of the
example's state, thereby releasing each example for garbage collection
after processing.

Note that this does not dereference state initialized in before(:all),
but those instance variables are cleared out in a separate process.

2. nullify ivars after each example

- Closes #321.
  • Loading branch information...
1 parent 7070a15 commit b51be2c42b5cd281549ee0af2af455d304b92b04 @dchelimsky dchelimsky committed Apr 7, 2011
Showing with 41 additions and 1 deletion.
  1. +4 −1 lib/rspec/core/example.rb
  2. +37 −0 spec/rspec/core/example_spec.rb
@@ -58,7 +58,10 @@ def run(example_group_instance, reporter)
rescue Exception => e
set_exception(e)
ensure
- @example_group_instance.example = nil
+ @example_group_instance.instance_variables.each do |ivar|
+ @example_group_instance.instance_variable_set(ivar, nil)
+ end
+ @example_group_instance = nil
begin
assign_auto_description
@@ -93,6 +93,14 @@ def assert(val)
end
describe "#run" do
+ it "sets its reference to the example group instance to nil" do
+ group = RSpec::Core::ExampleGroup.describe do
+ example('example') { 1.should eq(1) }
+ end
+ group.run
+ group.examples.first.instance_variable_get("@example_group_instance").should be_nil
+ end
+
it "runs after(:each) when the example passes" do
after_run = false
group = RSpec::Core::ExampleGroup.describe do
@@ -168,6 +176,35 @@ def assert(val)
"around (after)"
])
end
+
+ context "clearing ivars" do
+ it "sets ivars to nil to prep them for GC" do
+ group = RSpec::Core::ExampleGroup.describe do
+ before(:all) { @before_all = :before_all }
+ before(:each) { @before_each = :before_each }
+ after(:each) { @after_each = :after_each }
+ after(:all) { @after_all = :after_all }
+ end
+ example = group.example("does something") do
+ @in_example = :in_example
+ end
+ example_group_instance = group.new
+ example.run(example_group_instance, double('reporter').as_null_object)
+
+ %w[@before_all @before_each @after_each @after_all].each do |ivar|
+ example_group_instance.instance_variable_get(ivar).should be_nil
+ end
+ end
+
+ it "does not impact the before_all_ivars which are copied to each example" do
+ group = RSpec::Core::ExampleGroup.describe do
+ before(:all) { @before_all = "abc" }
+ example("first") { @before_all.should_not be_nil }
+ example("second") { @before_all.should_not be_nil }
+ end
+ group.run.should be_true
+ end
+ end
end
describe "#pending" do

0 comments on commit b51be2c

Please sign in to comment.