ACHTUNG. Das ist ein Archiv des alten forum.ruby-portal.de. Die aktuelle Mailingliste gibt es auf lists.ruby-lang.org/pipermail/ruby-de.

NOTICE. This is a ready-only copy of the old forum.ruby-portal.de. You can find the current mailing list at lists.ruby-lang.org/pipermail/ruby-de.

Die Programmiersprache Ruby

Blog|

Forum|

Wiki  


Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]

Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Garbage Collector, Ruby und C
BeitragVerfasst: 21 Dez 2006, 19:20 
Offline
Geselle

Registriert: 02 Nov 2006, 17:55
Beiträge: 103
Wohnort: Erfurt
Ich muss mal ganz blöd fragen, kann mir jemand was über den Garbage Collector erzählen und in wie weit ich den beachten muss wenn ich eine Ruby Klasse in C schreibe ?

Gruss beyama


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 21 Dez 2006, 19:55 
Offline
Interpreter
Benutzeravatar

Registriert: 05 Jun 2005, 01:54
Beiträge: 3225
EDIT: Whoops, jetzt habe ich den Zusatz "in C" uebersehen :oops: Wie es da aussieht weiss ich leider nicht genau, da ich mich noch nie damit beschaeftigt habe.

Hallo,

Kurz gesagt, der Garbage Collector (GC) ist dazu da hinter dir herzuraeumen, damit du dich nicht um die Speicherverwaltung kuemmern musst.

Lang gesagt: Nehmen wir ein kleines Beispiel her:

1
2
3
4
5
6
7
8
9
class Testa
def foo
bar = 42
end
end

Testa.new.foo

# Hier passieren noch mehr Sachen, die fuer dieses Beispiel aber nicht weiter von bedeutung sind
In diesem Codestueck passiert nix aufregendes; es wird nur eine neue Instanz von 'Testa' erzeugt und dann die Methode 'foo' aufgerufen. Im Hintergrund passiert aber einiges: Wenn du "Testa.new" aufrufst, belegt diese Instanz Speicher, der erst vom Betriebssystem angefordert werden muss. Das Betriebssystem fuehrt darueber Buch welches Programm welchen Speicher belegt. D.h. Ruby fordert vom Betriebssystem speicher an, welches sich in seiner "Belegt"-Liste notiert "Ruby gehoert nun dieser Speicherbereich mit der Adresse 0xSOUNDSO, Groesse X Bytes". Danach verwendet Ruby diesen Speicher um die Klasse darin zu erzeugen. Soweit, so gut.

Jetzt ists aber so dass gleich die Methode "foo" der soeben instanziierten Testa-Klasse aufgerufen wird, und sobald dieser Methodenaufruf fertig ist, benoetigen wir die Testa-Instanz nicht mehr. Dennoch belegt sie Speicher, auf den wir spaeter keinen Zugriff mehr haben (da wir die Instanz keiner Variablen zuweisen). Hier kommt der GC ins Spiel: In einer Sprache ohne GC waere das jetzt ein sog. Speicherleck, aber in Ruby (und anderen Sprachen) arbeitet der GC eng mit dem Interpreter zusammen, merkt sich welcher Speicher wo belegt wurde, und weiss ganz genau welcher Speicher nicht mehr benoetigt wird (was Ruby ihm mitteilt). Wenn der GC nun zum sammeln anfaengt, wird er entdecken dass unsere Instanz von keinem mehr gebraucht wird, und gibt sie wieder frei. Das heisst, er teilt dem Betriebssystem mit das Ruby den Speicher nicht mehr benoetigt, welches den Speicher nun aus seiner "Belegt"-Liste streicht und in seine "Frei"-Liste zurueckgibt.

Hoffe die Erklaerung war soweit verstaendlich.

_________________


1
2
3
alias L lambda
p L{|y|L{|f|y[L{|x|f[f][x]}]}[L{|f|y[L{|x|f[f][x]}]}]}[L{|z|L{|l|l.empty?? 0:1+z[l.drop(1)]}}][%w<a b c d e f g h i j>]
#=>10


Nuclear Powered Soup | Nuclear Powered Blog


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 21 Dez 2006, 20:12 
Offline
Geselle

Registriert: 02 Nov 2006, 17:55
Beiträge: 103
Wohnort: Erfurt
Soweit ist es mir klar, ich musste beim Programmieren mit C für Ruby, in der Init-Methode sagen mit welcher Funktion der Speicher angefordert wird, und in dieser Funktion hab ich ihm dann mitgeteilt mit welcher er den wieder frei geben kann. An der Stelle kann man aber eine weitere Funktion angeben die in den Tutorials irgend was mit "mark" heißt, Da muss also noch irgend was mehr sein als Speicher an zu fordern und wieder frei zu geben?
Und für was ist es von Interesse den GC aus zu schalten, denn dafür werden auch Funktionen bereit gestellt ?


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 21 Dez 2006, 20:41 
Offline
Böser Admin 2
Benutzeravatar

Registriert: 17 Mär 2004, 17:03
Beiträge: 2544
Wohnort: Berlin
verschoben: ich möchte solche themen gerne hier sammeln, da sie allesamt mit fortgeschrittenem Ruby zu tun haben.

_________________
Ruby-Mine | (almost) murphy.de | rubychan.de


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 21 Dez 2006, 22:10 
Offline
Interpreter

Registriert: 15 Mär 2005, 19:26
Beiträge: 6142
Wohnort: Karlsruhe
beyama hat geschrieben:
... in der Init-Methode sagen ...

... irgend was mit "mark" heißt ...

Was sind das für Funktionen? - Bitte schreib doch mal die komplette Definition oder einen Link auf die Doku in http://www.ruby-doc.org/.

Normalerweise überlässt man doch dem Ruby-Interpreter die Bereitstellung von Objekten mittels der rb_...-API-Funktionen.

Mir ist irgendwie nicht klar, was die Frage ist.

>>>>> EDIT >>>>>

Hab gerade gesehen um was es zu gehen scheint. Offensichtlich ist das Thema, dass ein Wrapper um existierende C-Datenstrukturen gelegt werden soll, um die dann von Ruby aus zu verwalten.

Tut mir leid, zu dem Thema kann ich nichts weiter sagen :cry:

_________________
WoNáDo.set_state!(:retired)


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 22 Dez 2006, 09:17 
Offline
Rubyist

Registriert: 26 Apr 2006, 21:35
Beiträge: 366
Hi,

die funktionen die du vll meinst können heissen wie du willst.
Es geht darum zwei funktionen anzugeben die dem gc sagen wann ein objekt
zum löschen freigegeben ist und wie eigentlich das objekt zu löschen ist.
Die zwei funktionen werden als parameter an Data_Wrap_Struct() und Data_Make_Struct() übergeben.
Bei meinen bisherigen ausflügen in die welt der extensions habe ich
die mark-funktion noch nicht gebraucht, wohl aber die free-funktion.
Per default verwendet man als free-funktion einfach free() aus der libc, manchmal
muss ein objekt aber mehr tun damit all der allokierte speicher wieder freigegeben wird.
Wie wir ja wissen benutzt der gc von ruby den mark-and-sweep-algorithmus.
D.h. alle objekte die nicht mehr gebraucht werden, werden markiert und dann später
freigegeben.

Markieren musst du allerdings afair nur rubyobjekte wenn deine strukture diese enthält.
Dafür gibt es die api-funktion rb_gc_mark().
Nehmen wir mal an deine struktur hätte neben einer verketten liste auch noch
einen zeiger auf ein ruby-array als member. Dann müsstest du das ruby-array
markieren und damit du das zum richtigen zeitpunkt machst, gibt es die möglichkeit
über die callbacks die aufforderung zu erhalten.
Hier mal ein auszug aus einer extension. Die benutzt zwar kein marking aber
die grundsätzliche benutzung der methoden wird gezeigt.
Die extension ist in c++ geschrieben.


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


//hier bekommst du die m��glichkeit rubyobjekte zum
//loeschen zu markieren
static void rxsb_engine_mark(rxsb::engine *e){
//rb_gc_mark(e->ruby_array);
}

static void rxsb_engine_free(rxsb::engine *e){
//wenn mehr freizugeben ist
//oder wie in meinem fall mit delete gel��scht werden soll
//kann man das hier tun
delete e;
}


static VALUE rxsb_engine_new(int argc,VALUE *argv,VALUE cl){
try{

VALUE self;
VALUE path_to_xsb;
rxsb::engine *engine_;

rb_scan_args(argc,argv,"01",&path_to_xsb);

if(!NIL_P(path_to_xsb)){
StringValue(path_to_xsb);
engine_ = new rxsb::engine(STR2CSTR(path_to_xsb));
}else{
engine_ = new rxsb::engine(XSB_PATH);
}

//hier werden die beiden funktionen als callbacks mit angegeben
self = Data_Wrap_Struct(cl,rxsb_engine_mark,rxsb_engine_free,engine_);

rb_obj_call_init(self,0,argv);

return self;

}catch(const rxsb::xsb_initialization_failed &ex){
rb_raise(rxsb_error_,"rxsb initialization failed");
}catch(...){
rb_raise(rxsb_error_,"bug: initialization of extension failed.");
}



HTH

greets

_________________



 callcc{|xx| callcc{|yy| lambda{|zz| zz}[yy]}[xx]}["Love Ruby but adore Scheme"]

Solve it once, adapt it to your needs => Schnipsel


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 23 Dez 2006, 22:39 
Offline
Geselle

Registriert: 02 Nov 2006, 17:55
Beiträge: 103
Wohnort: Erfurt
Sorry, ich hätte mich vielleicht etwas konkreter ausdrücken sollen.

closure hat geschrieben:
Wie wir ja wissen benutzt der gc von ruby den mark-and-sweep-algorithmus.
D.h. alle objekte die nicht mehr gebraucht werden, werden markiert und dann später
freigegeben.

Markieren musst du allerdings afair nur rubyobjekte wenn deine strukture diese enthält.
Dafür gibt es die api-funktion rb_gc_mark().
Nehmen wir mal an deine struktur hätte neben einer verketten liste auch noch
einen zeiger auf ein ruby-array als member. Dann müsstest du das ruby-array
markieren und damit du das zum richtigen zeitpunkt machst, gibt es die möglichkeit
über die callbacks die aufforderung zu erhalten.


Gut, dass wollte ich wissen.

Aber wann wird der callback-handler aufgerufen und reicht es nicht einfach rb_gc_mark()
in meiner free-funktion auf zu rufen?

Edit: Ich habs verstanden, in der mark-Funktion die man Data_Wrap_Struct() übergibt werden einfach alle intern genutzten Ruby-Objekte mit rb_gc_mark(ruby_objekt) markiert damit der GC weiß das er die beim zerstören des Objektes auch zerstören kann wenn sie sonnst nicht mehr gebraucht werden.


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
cron