Schrift
[thread]6373[/thread]

speicher freigeben (Seite 4)

Leser: 2


<< |< 1 2 3 4 >| >> 32 Einträge, 4 Seiten
Gast Gast
 2004-07-05 16:33
#83829 #83829
So 'teuer' ist das garnicht ...
im Prinzip wird lediglich jeweils ein Knoten aus dem Ring herausgebrochen, dem 'Vorgänger' der Wert des Nachfolgers zugewiesen und der 'Vorgänger' auf 'undef' gesetzt- zack & done.
Sicherlich - bei, sagen wir mal, ++10.000 Knoten kann sich das schon etwas ziehen ...
aber eine solche Anzahl von Knoten (Daten) ist sowieso nicht innerhalb des Speichers zu halten.
ptk
 2004-07-05 17:34
#83830 #83830
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=Crian,05.07.2004, 13:10]Wie würde man denn bei dem Modul Scalar::Util::weaken vorgehen? Bedeutet das Schwächen, dass diese Referenzen für die Referenzzählung nicht gezählt werden? Würde man dann die eine Richtung in obigem Kreis komplett schwächen, sowie eine Referenz der anderen Richtung?[/quote]
Man wuerde z.B. entweder alle back-Links oder alle next-Links schwaechen.

Eine einfache Moeglichkeit festzustellen, ob das automatische Aufraeumen funktioniert, ist die Verwendung einer einfachen Ausgabe in DESTROY:
Code: (dl )
1
2
3
sub DESTROY {
warn "DESTROY @_";
}

Wenn alles gut geht, sieht die Ausgabe ungefaehr so aus:
Code: (dl )
DESTROY Obj=HASH(0x81813f4) at /tmp/a.pl line 54.

Wenn das Aufraeumen nicht klappt, sieht die Ausgabe so aus:
Code: (dl )
DESTROY Obj2=HASH(0x8132fdc) at /tmp/a.pl line 101 during global destruction.

Man beachte "global destruction". Wenn der Perl-Interpreter beendet wird, dann wird noch einmal eine "klassische" Garbage Collection gestartet, die auch zirkulaere Referenzen aufraeumen kann, was bei eingebetteten Perl-Interpretern oder threads notwendig ist.

Hier ist --- nur zur Demostration von weaken --- eine quick'n'dirty-Implementation von doppelt verlinkten Listen. Oben ist eine Implementation mit einem Container (%linklist), wobei zirkulaere Referenzen von Anfang an vermieden werden. Die zweite Implementation verwendet Scalar::Util::weaken, wenn die mit "hier!" markierten Zeilen aktiviert werden.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/perl

{
package Obj;
my $next_id = 0;
our %linklist;
sub new {
my($class, $label, $prev, $next) = @_;
my $id = $next_id++;
my $prev_id = $prev->{id};
my $next_id = $next->{id};
my $self = bless {
id => $id,
label => $label,
prev => $prev_id,
next => $next_id,
}, $class;
$prev->{next} = $id;
$next->{prev} = $id;
$linklist{$id} = $self;
$self;
}
sub next {
my $self = shift;
if (defined $self->{next}) {
$linklist{$self->{next}};
}
}
sub prev {
my $self = shift;
if (defined $self->{prev}) {
$linklist{$self->{prev}};
}
}
sub traverse_forward {
my($self) = @_;
print $self->{label};
while(defined $self->{next}) {
$self = $linklist{$self->{next}};
print " " . $self->{label};
}
print "\n";
}
sub traverse_backward {
my($self) = @_;
print $self->{label};
while(defined $self->{prev}) {
$self = $linklist{$self->{prev}};
print " " . $self->{label};
}
print "\n";
}
sub DESTROY {
warn "DESTROY @_";
}
}

{
package Obj2;
use Scalar::Util qw(weaken);
sub new {
my($class, $label, $prev, $next) = @_;
my $self = bless {
label => $label,
prev => $prev,
next => $next,
}, $class;
$prev->{next} = $self;
$next->{prev} = $self;
# weaken $self->{prev} if $self->{prev}; # Hier!
# weaken $next->{prev} if $next->{prev}; # Hier!
$self;
}
sub next {
my $self = shift;
$self->{next};
}
sub prev {
my $self = shift;
$self->{prev};
}
sub traverse_forward {
my($self) = @_;
print $self->{label};
while(defined $self->{next}) {
$self = $self->{next};
print " " . $self->{label};
}
print "\n";
}
sub traverse_backward {
my($self) = @_;
print $self->{label};
while(defined $self->{prev}) {
$self = $self->{prev};
print " " . $self->{label};
}
print "\n";
}
sub DESTROY {
warn "DESTROY @_";
}
}

{
my $x1 = Obj->new("Null", undef, undef);
my $x2 = Obj->new("Eins", $x1, undef);
my $x3 = Obj->new("Zwei", $x2, undef);

$x1->traverse_forward;
$x3->traverse_backward;

%Obj::linklist = ();
}

{
my $x1 = Obj2->new("Null", undef, undef);
my $x2 = Obj2->new("Eins", $x1, undef);
my $x3 = Obj2->new("Zwei", $x2, undef);

$x1->traverse_forward;
$x3->traverse_backward;

}
<< |< 1 2 3 4 >| >> 32 Einträge, 4 Seiten



View all threads created 2004-07-01 15:11.