Your SlideShare is downloading. ×
循環参照のはなし
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,620
views

Published on

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

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

Published in: Technology

0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,620
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
13
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