Your SlideShare is downloading. ×
0
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
循環参照のはなし
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

循環参照のはなし

3,686

Published on

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

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

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,686
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
14
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 【5分】\n
  • 【5分】\n
  • 【5分】\n
  • 【5分】\n
  • \n
  • \n
  • \n
  • よい: リークしてるかの判定としては性格、わるい: 原始的、環境依存\n
  • よい: リーク全般を見つけられる、わるい: 結果の表示がごつい\n
  • よい: 結果がみやすい、だめ: 循環参照を探すだけ。XSのリークは検出できない。OUTER絡みも無理ぽ。\n\n
  • よい: 簡単にリーク検出、 わるい: オブジェクト限定\n
  • 【10分】よい: 解放タイミングが正確にわかる(中のクロージャから解放される) わるい: ひどいハック\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 【15分】undef エラーの原因となる。この例だとリークする。\n
  • この例だと、weakenよりこちらが自然\n
  • APIを変更し、クロージャを渡さずにすむようにする\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 甲斐互換のためにautorelease で返してくることがあるが、それだとうまくいかない。仕様をよく調べる必要あり。\n
  • \n
  • Transcript

    • 1. 2011.12.10 hiratara
    • 2. d.hatena.ne.jp/hirataratwitter.com/hirataraPerlYAPC gihyo.jp
    • 3. my ($ref1, $ref2, $ref3); $ref1 = $ref2; $ref2 = $ref3; $ref3 = $ref1;$ref1 $ref2 $ref3
    • 4. GCPerl GC
    • 5. mark-and-sweep GC
    • 6. mark-and-sweep GC
    • 7. mark-and-sweep GC
    • 8. mark-and-sweep GC
    • 9. reference counting 1 11 1 2 1 2 1
    • 10. reference counting 1 01 1 2 1 2 1
    • 11. reference counting 1 01 0 1 1 2 1
    • 12. reference counting 1 01 0 1 1 1 1
    • 13. reference counting 1 01 0 1 Leak 1 1 1
    • 14. (1) Template::Plugin::Filter (TT-2.2) Template::Pluginreturn $self->{ _STATIC_FILTER } ||= sub { $self->filter(shift);};
    • 15. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t sub { ... }
    • 16. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t sub { ... }
    • 17. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t
    • 18. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;}; $t
    • 19. (2) AnyEventmy $t; $t = AE::timer 1, 0, sub { ...; undef $t;};
    • 20. (3)my ($f, $x);(sub { $f = sub { $x } })->(); OUTSIDE sub {...} $f == sub { ... }
    • 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. 5( ≒ )
    • 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. 2) Test::LeakTraceuse Test::LeakTrace;no_leaks_ok { my $ref; $ref = $ref };
    • 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. 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. 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. 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. Devel::GladiatorPASS (181) FAIL (436)
    • 30. 5
    • 31. $self sub { ... }
    • 32. my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n";};$self->{handler}->(); sub { ... } $self “Hokkaido.pm”
    • 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. 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. 1)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n"; undef $self;};$self->{handler}->(); sub { ... } “Hokkaido.pm”
    • 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. 1)my $self = {name => "Hokkaido.pm", handler => undef};$self->{handler} = sub { print "Hello, ", $self->{name}, ".n"; undef $self;};$self->{handler}->();
    • 38. 1)( )($self->{handler} )
    • 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. 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. 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. 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. 4)AnyEvent::Handler $hdl->push_read (line => sub { my ($hdl, $line) = @_; ... });
    • 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. 5) Data::Decycledankogai guard 1)
    • 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. :Perl 5.8.8my $x = bless {}, "Dummy";(sub { $x; sub { $x } })->();my $x = bless {}, "Dummy";(sub { my $x = $x; sub { warn $x } })->();
    • 48. :Obj-C ARCretain release PerlCBRFuture *future = [[CBRFuture alloc] init];__weak CBRFuture *weakenFuture = future;leftHandle(self, ^(id e) { current = nil; leftSend(weakenFuture, e);});
    • 49. :Obj-C GuardNSString *local = @"OK";static void changeLocalValue(BOOL willBreak) { id original = local; CBRGuard *guard = [[CBRGuard alloc] initGuard:^{ local = original; }]; local = @"LOCALVALUE1";}
    • 50. :Obj-C Guard autorelease

    ×