Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

循環参照のはなし

5,058 views

Published on

循環参照の見つけ方と直し方の話

Published in: Technology
  • Be the first to comment

循環参照のはなし

  1. 1. 2011.12.10 hiratara
  2. 2. d.hatena.ne.jp/hirataratwitter.com/hirataraPerlYAPC gihyo.jp
  3. 3. my ($ref1, $ref2, $ref3); $ref1 = $ref2; $ref2 = $ref3; $ref3 = $ref1;$ref1 $ref2 $ref3
  4. 4. GCPerl GC
  5. 5. mark-and-sweep GC
  6. 6. mark-and-sweep GC
  7. 7. mark-and-sweep GC
  8. 8. mark-and-sweep GC
  9. 9. reference counting 1 11 1 2 1 2 1
  10. 10. reference counting 1 01 1 2 1 2 1
  11. 11. reference counting 1 01 0 1 1 2 1
  12. 12. reference counting 1 01 0 1 1 1 1
  13. 13. reference counting 1 01 0 1 Leak 1 1 1
  14. 14. (1) Template::Plugin::Filter (TT-2.2) Template::Pluginreturn $self->{ _STATIC_FILTER } ||= sub { $self->filter(shift);};
  15. 15. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t sub { ... }
  16. 16. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t sub { ... }
  17. 17. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t
  18. 18. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t
  19. 19. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;};
  20. 20. (3)my ($f, $x);(sub { $f = sub { $x } })->(); OUTSIDE sub {...} $f == sub { ... }
  21. 21. (3)use Devel::Peek; Dump($f);SV = IV(0x100827fd8) at 0x100827fe0 REFCNT = 2 RV = 0x100827878 SV = PVCV(0x10082b5f8) at 0x100827878 REFCNT = 1 GVGV::GV = 0x100856bc0 "main" :: "__ANON__" OUTSIDE = 0x1008032a0 (ANON) SV = PVCV(0x100852a90) at 0x1008032a0 REFCNT = 1 GVGV::GV = 0x100856bc0 "main" :: "__ANON__" PADNAME = 0x1008277e8(0x100287000) PAD = 0x100827800(0x10025c0e0) 1. 0x100827fe0<2> FAKE "$f" flags=0x0 index=1
  22. 22. 5( ≒ )
  23. 23. 1) ps% perl for (1 .. 10000) { my $ref; $ref = $ref; warn `ps -o rss= -p $$` if $_ % 1000 == 0; } 1272 1304 1328 1352 1376...
  24. 24. 2) Test::LeakTraceuse Test::LeakTrace;no_leaks_ok { my $ref; $ref = $ref };
  25. 25. 2) Test::LeakTraceuse Test::LeakTrace;no_leaks_ok { my $ref; $ref = $ref }; not ok 1 - leaks 1 <= 0 # Failed test leaks 1 <= 0 # at - line 4. # 1 # <= # 0 # leaked REF(0x10083b610) from - line 4. # SV = IV(0x10083b608) at 0x10083b610 # REFCNT = 1 # FLAGS = (PADMY,ROK) # RV = 0x10083b610 # SV = IV(0x10083b608) at 0x10083b610 # REFCNT = 1 # FLAGS = (PADMY,ROK) # RV = 0x10083b610 # SV = IV(0x10083b608) at 0x10083b610 # REFCNT = 1 # FLAGS = (PADMY,ROK) # RV = 0x10083b610 # SV = IV(0x10083b608) at 0x10083b610 ...
  26. 26. 3) Devel::Cycleuse Devel::Cycle;my ($ref1, $ref2, $ref3);$ref1 = $ref2;$ref2 = sub { $ref3 };$ref3 = [$ref1];find_cycle($ref1);Cycle (1): $$A => &B $B variable $ref3 => $C $$C => @D $D->[0] => $A
  27. 27. 4) Devel::Leak::Objectuse Devel::Leak::Object qw{GLOBAL_bless};$Devel::Leak::Object::TRACKSOURCELINES = 1;my $ref; $ref = bless $ref => "XXX";Tracked objects by class: XXX 1Sources of leaks:XXX 1 from - line: 3
  28. 28. 5) DESTROYsub Ref1::DESTROY { warn "destroyed REF1" }sub Ref2::DESTROY { warn "destroyed REF2" }my $x;my $f = bless sub { $x; bless sub { $x } => "Ref2";} => "Ref1";$f->();destroyed REF2 at - line 2.destroyed REF1 at - line 1.
  29. 29. Devel::GladiatorPASS (181) FAIL (436)
  30. 30. 5
  31. 31. $self sub { ... }
  32. 32. my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n";};$self->{handler}->(); sub { ... } $self “Hokkaido.pm”
  33. 33. 1)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n"; undef $self;};$self->{handler}->(); sub { ... } $self “Hokkaido.pm”
  34. 34. 1)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n"; undef $self;};$self->{handler}->(); sub { ... } $self “Hokkaido.pm”
  35. 35. 1)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n"; undef $self;};$self->{handler}->(); sub { ... } “Hokkaido.pm”
  36. 36. 1)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n"; undef $self;};$self->{handler}->(); sub { ... } “Hokkaido.pm”
  37. 37. 1)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n"; undef $self;};$self->{handler}->();
  38. 38. 1)( )($self->{handler} )
  39. 39. 2) Scalar::Util::weakenmy $self = {name => "Hokkaido.pm", handler => undef};Scalar::Util::weaken(my $weaken_self = $self);$self->{handler} = sub { print "Hello, ", $weaken_self->{name}, ".n";};$self->{handler}->(); sub { ... } $self “Hokkaido.pm”
  40. 40. 2) Scalar::Util::weakenmy $self = {name => "Hokkaido.pm", handler => undef};Scalar::Util::weaken($self); #$self->{handler} = sub { print "Hello, ", $self->{name}, ".n";};$self->{handler}->();
  41. 41. 3)my $self = {name => "Hokkaido.pm", handler => undef};my $name = $self->{name};$self->{handler} = sub { print "Hello, ", $name, ".n";};$self->{handler}->(); sub { ... } $self “Hokkaido.pm”
  42. 42. 4)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { my $self = shift; print "Hello, ", $self->{name}, ".n";};$self->{handler}->($self); sub { ... } $self “Hokkaido.pm”
  43. 43. 4)AnyEvent::Handler $hdl->push_read (line => sub { my ($hdl, $line) = @_; ... });
  44. 44. 5) Data::Decycleuse Data::Decycle;my $guard = Data::Decycle->new( my $self = {name => "Hokkaido.pm", handler => undef});$self->{handler} = sub { "Hello, ", $self->{name}, ".n";};$self->{handler}->();
  45. 45. 5) Data::Decycledankogai guard 1)
  46. 46. :Perl 5.8.8use Devel::Leak::Object qw{GLOBAL_bless};bless my $x = {}, "Dummy";(sub { sub { $x } })->();Tracked objects by class: Dummy 1
  47. 47. :Perl 5.8.8my $x = bless {}, "Dummy";(sub { $x; sub { $x } })->();my $x = bless {}, "Dummy";(sub { my $x = $x; sub { warn $x } })->();
  48. 48. :Obj-C ARCretain release PerlCBRFuture *future = [[CBRFuture alloc] init];__weak CBRFuture *weakenFuture = future;leftHandle(self, ^(id e) { current = nil; leftSend(weakenFuture, e);});
  49. 49. :Obj-C GuardNSString *local = @"OK";static void changeLocalValue(BOOL willBreak) { id original = local; CBRGuard *guard = [[CBRGuard alloc] initGuard:^{ local = original; }]; local = @"LOCALVALUE1";}
  50. 50. :Obj-C Guard autorelease

×