Dynamisch geladener Code

461 Aufrufe

Veröffentlicht am

Ein Artikel aus dem alten Blog…

Veröffentlicht in: Internet
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
461
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
5
Aktionen
Geteilt
0
Downloads
4
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Dynamisch geladener Code

  1. 1. Dynamisch geladener Code Die wunderbare Welt von Isotopp Samstag, 8. Oktober 2005 Dynamisch geladener Code Inzwischen  bin  ich  so  weit,  daß  ich  viele  Unix­Kommandozeilenprogramme  zwar nützlich  finde,  aber  in  einem  größeren  Maßstab  als  unhandlich  und  schlecht wiederzuverwenden ansehe. Das liegt daran, daß das Konzept der Pipeline und der Kommandozeile zwar sehr mächtig sind, insbesondere wenn man sie mit einer guten Shell verwendet, aber einen nur so weit bringen. Manchmal  muß  man  doch  richtigen  Code  schreiben,  und  wenn  man  dann  den Compiler oder auch nur eine Scriptsprache schwingen muß, dann nützen einem die ganzen  Kommandozeilen­Utilities  gar  nichts  mehr.  Ja,  es  geht  sogar  so  weit,  daß sich diese ganzen Hilfsmittel als gefährlich erweisen, wenn irgendein Schlaumeier in seiner  Gedankenlosigkeit  Benutzereingaben  und  Kommandozeilenbefehle zusammenmischt  und  dann  ohne  das  Gehirn  einzuschalten  an  "system()"  oder "popen()"  übergibt.  Die  Geschichte  von  PHP  und  Perl  ist  voll  von  solchen bedauerlichen Betriebsunfällen und tausende von deface­ten Webseiten existieren, um Zeugnis davon abzulegen. Recode ist so ein Utilitiy gewesen, daß ich nützlich gefunden hätte, wenn ich es ­ damals  ­  in  den  nn  hätte  einbauen  können.  Aber  eine  librecode  gab  es  nicht  ­ immerhin hat man einen Bugreport irgendwann erhört und eine solche erzeugt und so war es dann ganz einfach, die entsprechende PHP Extension zu schreiben. Tidy ist  ebenso  ein  Fall,  der  als  Bibliothek  sehr  viel  nützlicher  gewesen  wäre  als  als Kommandozeilenprogramm,  und  immerhin  gibt  es  inzwischen  auch  eine  Libtidy, auch wenn Suse Tidy per Default ohne diese baut und man daher das Suse­Paket erst  einmal  durch  was  richtiges  ersetzen  muß,  bevor  man  sich  ein  zeitgemäßes PHP5 übersetzt. Es  gibt  eine  ganze  Reihe  von  Programmen,  die  ich  ebenfalls  sehr  viel  lieber  als Bibliotheken  sehen  würde  statt  als  Standalone­Programme  ­  allen  voran  den  C­ Compiler selber. Wie coole Sachen könnte man machen, stünde einem Funktionalität wie die Folgende bereit. char *code = "void function(void) { printf("Hello, Worldn"); }"; void (*f)(void); PARSETREE_T *t = parse(code); EXEC_T *e = compile(t); f = find_symbol(e, "function"); if (f) f(); Oder bin ich der einzige, der so etwas cool finden würde?
  2. 2. Aber  auch  ohne  die  Rekursion  der  Bibliothekserzeugung  durch  Bibliotheken  kann man nützliche Dinge tun. Und das geht so... Ein Stück monolithischer Code #include <stdio.h> int func(int para) {         int result;         printf("Entering func(%d)n", para);         result = 3 * para;         printf("Leaving func(%d) = %dn", para, result);         return result; } int main(int argc, char *argv[]) {         printf("main startn");         printf("Calling func(4) = %dn", func(4));         printf("main endn");         return 0; } Das ist ein mächtig aufregendes Programm: Es hat eine Funktion "func", die ihren numerischen Eingabewert mit drei multipliziert und zurückgibt. Es besteht aus einem Stück und ist trivial zu übersetzen und auszuführen: .PHONY: clean prog: prog.c         cc ­Wall ­o prog prog.c clean:         rm prog Zwei einzelne Module Für  so  ein  kleines  Testprogramm  wie  dieses  ist  das  ausreichend,  aber  wenn Programme  größer  werden,  wollen  wir  sie  aufteilen.  Wir  bekommen  drei Teilprogramme. Das erste, func.c, enthält unsere Rechenfunktion: #include <stdio.h> #include "func.h" int func(int para) {         int result;         printf("Entering func(%d)n", para);         result = 3 * para;         printf("Leaving func(%d) = %dn", para, result);         return result;
  3. 3. } Der zweite Teil, prog.c, ruft diese Funktion nun auf: #include <stdio.h> #include "func.h" int main(int argc, char *argv[]) {         printf("main startn");         printf("Calling func(4) = %dn", func(4));         printf("main endn");         return 0; } Der dritte Teil, func.h, ist winzig klein: extern int func(int para); Die "extern"­Anweisung in dieser Include­Datei muß in prog.c eingebunden werden. Sie macht dem Compiler, der prog.c übersetzt, klar, daß es eine Funktion func() gibt, und  welche  Parameter  sie  ergibt  sowie  welches  Ergebnis  sie  liefert.  Ohne  diese Include­Datei würde der Compiler nicht wissen, daß es eine solche Funktion gibt und einen Fehler generieren. Mit dem Include vertagt er seine Entscheidung auf später, und  generiert  lediglich  eine  "undefined  reference"  auf  die  Funktion,  die  dann  zu einem  späteren  Zeitpunkt  gefunden  und  gelinkt  werden  muß.  Bevor  wir  uns  das genauer ansehen, hier erst einmal das Makefile: prog:   prog.o func.o         cc ­o prog $^ .PHONY:         clean .c.o:         cc ­Wall ­c $< clean:         rm ­f *.o prog .dependencies .dependencies:         cc ­MM *.c > .dependencies include .dependencies Ein Testlauf: kris@valiant:~/Source/dlopen/02­multifile> make clean rm ­f *.o prog .dependencies kris@valiant:~/Source/dlopen/02­multifile> make Makefile:18: .dependencies: Datei oder Verzeichnis nicht gefunden
  4. 4. cc ­MM *.c > .dependencies cc ­Wall ­c prog.c cc ­Wall ­c func.c cc ­o prog prog.o func.o kris@valiant:~/Source/dlopen/02­multifile> ./prog main start Entering func(4) Leaving func(4) = 12 Calling func(4) = 12 main end Unser Makefile generiert also mit mehreren einzelnen Compileraufrufen eine "prog.o" und eine "func.o"­Datei. Ein dritte Aufruf fügt dann "prog" aus "prog.o" und "func.o" zusammen.  Wenn  wir  einmal  einen  genaueren  Blick  auf  diese  Dateien  werden, erkennen wir, wie das funktioniert: kris@valiant:~/Source/dlopen/02­multifile> nm func.o 00000000 T func U printf kris@valiant:~/Source/dlopen/02­multifile> nm prog.o U func 00000000 T main U printf Die  Datei  prog.o  enthält  ein  "U  func",  ein  "undefined  symbol"  für  die  Funktionen "func" und "printf". Sie definiert ein Symbol "main". Die Datei func.o enthält ebenfalls ein  "undefined  symbol"  für  "printf",  und  definiert  ein  Symbol  "func".  Durch  das Zusammenfügen  beider  Dateien  wird  das  undefinierte  Symbol  "func"  mit  der Definition  für  "func"  aufgefüllt.  Es  bleibt  jetzt  noch  die  Definition  von  "printf"  zu erfüllen ­ dies geschieht mit der libc, die jedem C­Programm automatisch zugeügt wird,  wenn  man  dies  nicht  abbestellt.  Der  C­Startupcode,  der  sich  auch  um  die Parameterbehandlung  mit  argc  und  argv  kümmert,  ruft  dann  "main"  auf.  Er  kann dies, weil "main" ein definiertes (und exportiertes) Symbol ist, sodaß er die Funktion finden kann. Eine statische Bibliothek bauen und verwenden Wir  können  dieses  Code  nun  ohne  Änderung  verwenden,  um  eine  statische Bibliothek  zu  bauen  und  zu  verwenden.  Dazu  müssen  wir  lediglich  die Zusammenbauanweisung,  das  Makefile,  anpassen.  Unser  neues  Makefile  sieht  so aus: prog:   prog.o libfunc.a         cc ­o prog prog.o ­L. ­lfunc .PHONY:         clean .c.o:         cc ­Wall ­c $< libfunc.a:      func.o         ar rcs $@ $? clean:
  5. 5.         rm ­f *.o *.a prog .dependencies .dependencies:         cc ­MM *.c > .dependencies include .dependencies und es tut dies: kris@valiant:~/Source/dlopen/03­staticlib> make Makefile:19: .dependencies: Datei oder Verzeichnis nicht gefunden cc ­MM *.c > .dependencies cc ­Wall ­c prog.c cc ­Wall ­c func.c ar rcs libfunc.a func.o cc ­o prog prog.o ­L. ­lfunc Wie  zuvor  übersetzen  wir  unsere  beiden  .c­Dateien  in  .o­Dateien.  Alle Bibliotheksmodule fügen wir nun in eine Bibliothek "libfunc.a" ein. Hier ist dies nur eine Datei, func.o, aber in einem richtigen Projekt könne das sehr viele Dateien sein. Zum  Erzeugen  der  Bibliothek  verwenden  wir  den  Archiver,  ar.  Mit  der  Option  "r" ("Replace", also entweder einfügen aktualisieren von Bibliotheksmodulen) fügen wir func.o in die neue Bibliothek ein. Die Suboption "c" ("Create", Anlegen der Bibliothek bei Bedarf) sorgen wir dafür, daß die Bibliothek auch erzeugt wird, wenn sie noch nicht  existiert.  Die  Suboption  "s"  erzeugt  einen  Objektindex  im  Archiv  oder aktualisiert  diesen.  Dies  erleichtert  dem  Linker  später  die  Arbeit,  wenn  er  das Programm aus Bibliotheksmodulen zusammenbauen muß. Unser  Programm­Modul  prog.o  enthält  nun  ein  undefined  Symbol,  "func".  Mit  der Option "­L" setzen wir den Suchpfad für Bibliotheken, und zwar auf ".", das aktuelle Verzeichnis.  Dort  suchen  wir  mit  "­lfunc"  nach  der  Bibliothek  "libfunc.a".  Alle  .o­ Dateien  in  der  libfunc.a  werden  durchsucht.  Wenn  eine  von  ihnen  das  gesuchte Symbol  "func"  enthält,  wird  diese  .o­Datei  dem  Programm  zugefügt.  Dadurch  wird "func" von der Liste der undefined symbols gestrichen und es werden ggf. weitere undefined symbols der Liste hinzugefügt, nämlich diejenigen, die das Modul "func.o" selber  mitbringt,  wenn  es  dem  Programm  hinzugefügt  wird  ­  in  unserem  Beispiel "printf". Aber "printf" war ja sowieso schon auf der Liste der undefinierten Symbole, denn es wird ja auch in prog.o verwendet. Es  ist  wichtig,  eine  Bibliothek  so  zu  schreiben,  daß  sie  aus  vielen  kleinen Objektdateien besteht ­ jeweils eine Funktion pro Objektdatei. Das muß so sein, weil der Linker für jedes undefined symbol die Objektdatei aus dem Archiv extrahiert und dem Programm hinzufügt, die eine Definition für das gesuchte Symbol enthält. Wenn die Objektdateien groß sind und viele Funktionen enthalten, dann werden unserem Endprogramm  unter  Umständen  Funktionen  zugefügt,  die  wir  gar  nicht  brauchen, weil sie in derselben Objektdatei stehen wie eine Funktion, die wir brauchen. Unsere Programme werden dann unnötigt groß. Dynamische Bibliotheken Bei statischen Bibliotheken enthält nun jedes Programm, das wir schreiben und in dem wir "func" verwenden, eine Kopie von "func". Wenn wir drei oder vier von diesen Programmen zugleich starten, dann stehen auf dem Rechner drei oder vier Kopien von "func" im Speicher. Das muß nicht so sein. Wir können ­ wieder ohne Code zu
  6. 6. ändern  ­  unser  Programm  so  bauen,  daß  es  stattdessen  dynamische  Bibliotheken verwendet. Eine dynamische Bibliothek wird immer als Ganzes geladen, steht dafür aber nur einmal im Speicher. Wenn also drei oder vier verschiedene Programme die Bibliothek  verwenden,  wird  sie  zwar  für  jedes  dieser  Programme  in  dessen Speicherbereich  eingeblendet,  verbraucht  dafür  aber  nur  einmal  physikalischen Speicher. Damit das funktioniert, ändern wir das Makefile noch einmal ab: prog:   prog.o libfunc.so         cc ­o prog prog.o ­L`pwd` ­lfunc ­Wl,­rpath `pwd` .PHONY:         clean .c.o:         cc ­Wall ­c $< libfunc.so:     func.o         cc ­rdynamic ­shared ­o libfunc.so func.o clean:         rm ­f *.o *.a *.so prog .dependencies .dependencies:         cc ­MM *.c > .dependencies include .dependencies Der Build sieht jetzt so aus: kris@valiant:~/Source/dlopen/04­dynamiclib> make Makefile:20: .dependencies: Datei oder Verzeichnis nicht gefunden cc ­MM *.c > .dependencies cc ­Wall ­c prog.c cc ­Wall ­c func.c cc ­rdynamic ­shared ­o libfunc.so func.o cc ­o prog prog.o ­L`pwd` ­lfunc ­Wl,­rpath,`pwd` Hier  werden  die  Objektmodule  ohne  eigene  "main"­Funktion  nicht  mit  "ar"  in  eine "lib*.a"­Datei überführt, sondern mit einem "cc"­Aufruf in eine .so­Datei umgewandelt. So  wie  man  "nm"  auf  Objektdateien  (*.o)  und  Bibliotheken  (*.a)  anwenden  kann, kann  man  mit  "objdump  ­T  libfunc.so"  eine  Liste  der  in  der  .so­Datei  definierten Symbole bekommen ­ leider bekommt man neben den interessanten Informationen auch  noch  eine  ganze  Menge  Verwaltungsklimbim  angezeigt,  sodaß  man  das Ergebnis ein wenig filtern muß, bevor man es sinnvoll lesen kann. Der  eigentliche  Build­Aufruf  ist  "cc  ­o  prog  prog.o  ­L`pwd`  ­lfunc  ­Wl,­rpath,`pwd`". Die  Optionen  "­L"  und  "­l"  funktionieren  genau  wie  bei  statischen  Bibliotheken.  Mit der  Option  "­Wl"  wird  eine  Option  an  den  Linker  weitergegeben,  den  wir  mit  "­ rpath,`pwd`" instruieren, das aktuelle Verzeichnis als Suchpfad für die dynamischen Bibliotheken im resultierenden Binary mit zu vermerken. Wenn wir das nicht täten, würde  libfunc.so  nicht  gefunden  werden,  solange  wir  sie  nicht  in  einem  der  in /etc/ld.so.conf genannten Verzeichnisse installieren und einmal "ldconfig" aufrufen.
  7. 7. Wer dem Linker bei der Arbeit zuschauen will, der kann dies tun, indem er die Shell­ Variable "LD_DEBUG" setzt und exportiert. Der Wert "help" zeigt einem, auf was für Werte man LD_DEBUG setzen kann: kris@valiant:~/Source/dlopen/04­dynamiclib> export LD_DEBUG=help kris@valiant:~/Source/dlopen/04­dynamiclib> ./prog Valid options for the LD_DEBUG environment variable are: libs display library search paths reloc display relocation processing files display progress for input file symbols display symbol table processing bindings display information about symbol binding versions display version dependencies all all previous options combined statistics display relocation statistics unused determined unused DSOs help display this help message and exit To direct the debugging output into a file instead of standard output a  filename  can  be  specified  using  the  LD_DEBUG_OUTPUT environment variable. dlopen() Manchmal kann man zur Compilezeit noch nicht vorhersagen, welche Module das laufende  Programm  später  einmal  benötigen  wir.  Speziell  Programme  mit  Plugin­ Architekturen haben den Bedarf, .so­Dateien zur Laufzeit anziehen zu können, um so ihre  Funktionalität  durch  das  Laden  von  Plugins  zu  erweitern.  Während  statisch eingebundene  .so­Dateien  keine  Änderungen  am  Code  notwendig  machen,  ist  für dynamisch geladene Dateien ein wenig Änderung notwendig ­ allerdings nur auf der ladenden  Seite.  Auf  der  Seite  des  Bibliothekscodes,  in  unserem  Falle  also  func.c, func.o und libfunc.so, ist keine Änderung notwendig. Das Makefile sieht nun jedoch so aus: all:    prog libfunc.so prog:   prog.o         cc ­o prog prog.o ­ldl .PHONY:         clean all .c.o:         cc ­Wall ­c $< libfunc.so:     func.o         cc ­rdynamic ­shared ­o libfunc.so func.o clean:         rm ­f *.o *.a *.so prog .dependencies .dependencies:         cc ­MM *.c > .dependencies
  8. 8. include .dependencies Wir  haben  nun  also  zwei  unabhängige  Targets  beim  Build:  Die  .so­Datei  und  das Programm,  das  sie  verwendet,  teilen  keine  gemeinsame  Abhängigkeit  mehr.  Das Programm, prog, wird nun auch nicht mehr gegen die .so­Datei gelinkt. Stattdessen wird  mit  "­ldl"  die  libdl  eingebunden,  die  uns  die  Funktionen  dlopen(),  dlsym()  und dlclose() bereitstellt. Der Code in prog.c sieht nun so aus: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dlfcn.h> #define LIBNAME "./libfunc.so" typedef int (*func_t)(int); int main(int argc, char *argv[]) {         func_t f;         char *error_msg;         void *libhandle   = NULL;         printf("main startn");         /* .so oeffnen */         libhandle = dlopen(LIBNAME, RTLD_LAZY);         if (!libhandle) {                 fprintf(stderr, "dlopen(%s, RTLD_LAZY failed: %sn",                          LIBNAME,                          dlerror()                 );                 exit(2);         }         printf("dlopen() = %pn", libhandle);         /* func() finden */         error_msg = dlerror();         f = dlsym(libhandle, "func");         error_msg = dlerror();         if (error_msg) {                 fprintf(stderr, "dlsym(%p, "func") failed: %sn",                          libhandle,                         error_msg                 );                 exit(3);         }         /* func() aufrufen */         printf("Calling func(4) = %dn", f(4));
  9. 9.         /* .so droppen */         dlclose(libhandle);         printf("main endn");         return 0; } Dieser Code definiert eine Variable f vom Typ "Zeiger auf eine Funktion, die ein int liefert  und  einen  int­Parameter  annimmt.  Er  lädt  mit  "dlopen()"  die  "libfunc.so"  ein. Wenn dies gelingt, steht ein Handle für die Bibliothek zur Verfügung. Mit "dlsym()" können wir mit Hilfe des Handles in dieser Bibliothek nach der dem Symbol "func" suchen  und  bekommen  so  einen  Zeiger  auf  "func"  in  f  abgelegt  oder  nicht.  Man beachte  das  Errorchecking  für  das  Ergebnis  von  dlsym()  nach  Lehrbuch  ­  das Interface von dlsym() ist mehr als beklopptnicht sehr schön designed. Wir können f dann ganz normal aufrufen. "dlclose()" entlädt das Plugin dann wieder. Wenn mehr Leute sich angewöhnen würden, ihre Programme in Form von Bibliothek und Kommandozeilenwrapper zu schreiben, wäre es sehr viel leichter, Code in Form von Bibliotheken in Sprachkerne wie PHP oder in andere Programme einzubinden. Technisch  ist  das  nicht  sehr  schwer,  solange  man  sich  die  Mühe  macht,  die Infrastruktur  drumherum  in  Form  von  Makefiles  und  Include­Dateien  ordentlich  zu erstellen. Material Das  Program  Library  Howto  zeigt  den  ganzen  Kram  noch  einmal  in  aller Ausführlichkeit.  Ein  PDF  von  Ulrich  Drepper  diskutiert  die  dabei  ablaufenden Interna. Das C++ dlopen Mini­Howto beschreibt, wie das ganze mit C++ zu bewerkstelligen ist. James Norton baut da in Dynamic Class Loading in C++ sogar einen schönen Wrapper drumherum. Dynamic C++ Classes ­ Code Distribution ist die Downloadseite der dynamic­class library für C++. Das Paper "Dynamic C++ classes: A lightweight mechanism to update  code  in  a  running  program"  von  Gísli  Hjálmtýsson  and  Bob  Gray beschreibt den Hintergrund. Geschrieben von Kristian Köhntopp in Computer um 12:21 | Kommentare (14) | Trackbacks (4) Trackbacks Trackback­URL für diesen Eintrag Wie ich blogge?! ­ Die Weblog­Umfrage 2005 Beim "vollständigen" lesen von "Dynamisch geladener Code " (für mich als Nicht­ Programmierer sehr interessant) bei Kris eher zufällig über die Weblog­Umfrage 2005 gestolpert. Infos gibt es auf http://www.bamberg­gewinnt.de/wordpress/wieic Weblog: meersau Aufgenommen: Okt 08, 18:22 Gefunden bei Kris: Dynamisch geladener Code Kris hat vor seinem Einstieg in den neuen Job wohl derzeit etwas zu viel Zeit und schubst einen tollen Grundlagenartikel nach dem anderen in sein Blog. Heute gefunden: Dynamisch Geladener Code Weblog: Zugschlusbeobachtungen
  10. 10. Aufgenommen: Okt 08, 19:33 Dynamisch generierter Code Kristian Köhntopp erklärt in "Dynamisch geladener Code" den Aufbau von Programmen in verschiedenen Variationen, wie monolitischen Code, Code in mehreren Modulen, mit statischen Bibliotheken, dynamischen Bibliotheken und das Zuladen von Code mithilfe der d Weblog: hochniveau: Das offizielle Blog der h8u.de Gemeinde Aufgenommen: Okt 09, 20:18 Porting CouchDb to Unix CouchDb is a document database. It stores information based around the concept of documents rather than tables and rows like traditional relational databases do. When I had a look at it earlier, it was available for Windows only. This made me go to other Weblog: plok Aufgenommen: Okt 22, 14:12 Kommentare Ansicht der Kommentare: (Linear | Verschachtelt) Greenspun's Tenth Rule of Programming: Any sufficiently complicated C or Fortran program contains an ad hoc, informally­ specified, bug­ridden, slow implementation of half of Common Lisp. #1 Django am 08.10.2005 15:05 Das waren in etwa auch die Worte der Katze heute beim Abwaschen, als wir über den Artikel sprachen. #1.1 Isotopp (Link) am 08.10.2005 15:27 Ich weiß ja nicht, inwieweit Java zur Diskussion steht, aber das bringt z.B. einen ClassLoader mit, der Klassen aus $CLASSPATH, aus dem Web oder sonstwo holen, laden und (per Default­Konstruktor) instantieeren kann. Plugin­Mechanismen werden damit zum Kinderspiel... #2 Andreas Lenz (Link) am 08.10.2005 15:32 deswegen benutz ich java. ein einheitlicher bytecode ist schon was wert. Und die damit möglichen Plugin Architekturen sind doch deutlich schmerzfreier als sich mit ELF Loadern herumzustreiten. Alternativ bietet sich .NET an, was auch ne feine Sache ist. Wenn beides nur nicht so langsam wäre :) Siehe auch http://rmh.blogs.com/thisisjava/2005/03/compilation_and.html Gruss Bernd #3 Bernd Eckenfels (Link) am 08.10.2005 17:39 "Wenn beides nur nicht so langsam wäre." Um es mit dem Schockwellenreiter zu sagen: 'Es gibt zwei Arten von Narren. Die einen sagen: "Das war schon immer so, und deshalb ist es gut!" Und die anderen sagen: "Das ist neu, und deshalb ist es besser."' #3.1 Isotopp (Link) am 08.10.2005 18:00
  11. 11. Ja, und es gibt die die sagen es sei nicht langsam :) #3.1.1 Bernd Eckenfels (Link) am 08.10.2005 19:05 Das wirkliche Problem von .NET ist doch derzeit, dass die heutige Wintel­ Rechnerarchitektur mit ihrer relativ harten 2­GB­Grenze für die Menge an Hauptspeicher einfach nicht für ein Framework gedacht ist, bei dem einzelne Instanzen einer nur mittelkomplexen Applikation einen Memory Footprint von 800 MB haben. #3.2 Marc 'Zugschlus' Haber (Link) am 08.10.2005 19:31 Ist das Problem damit der begrenzte Speicher, oder die gnadenlose Ressourcenaserei von .NET, Java und Konsorten? Mir persoenlich kommt ja die Galle hoch bei jeder Hochsprache, die meint, besser als ich zu wissen wann ich die Daten im Speicher nicht mehr brauche. Wozu eine halbwegs aktuelle JRE 15MB RAM fuer ein HalloWelt braucht, wird mir nie in den Kopf gehen. Bei .NET siehts da auch nicht besser aus, da wird auch erstmal das ganze Framework in den Speicher gesaugt bevor man feststellt dass davon eigentlich garnichts benoetigt wird... #3.2.1 Woo am 08.10.2005 21:13 Ja, die HalloWelt­produzierende Industrie ist schon gestraft. In den Regalen liegen die HalloWelt­Programme schwer wie Blei. Will keiner haben, weil zu viel Speicher gebraucht wird. #3.2.1.1 Stefan Scholl (Link) am 08.10.2005 22:08 .net laeuft doch auf x86, und dank PAE war die 2GB Grenze noch nie ein echtes Problem. #3.2.2 Bernd Eckenfels (Link) am 09.10.2005 06:14 x64 sollte das heissen. #3.2.2.1 Bernd Eckenfels (Link) am 09.10.2005 23:47 Mit libtcc aus dem Tiny C Compiler kannst du zur Laufzeit C Code compilieren und aufrufen. Der Beispielcode dazu in libtcc_test.c sieht fast so aus, wie dein einleitendes Codestueck. #4 Anonym am 09.10.2005 17:15 So lustig dynamisch kompilierter Code ja ist: laeuft das nicht dem Wunsch entgegen, keinen ausfuehrbaren Code auf dem Stack (und heap) zu haben? Vor allen nachdem im Intel­Lager langsam Prozessoren kommen, die das tatsaechlich durchsetzen koennen. #5 Lalufu am 10.10.2005 09:32 Microsoft antwortet auf LLVM und produziert dies. Sehr spannend. #6 Kristian Köhntopp (Link) am 17.09.2011 05:43 Kommentar schreiben Name E­Mail Homepage Antwort zu [ Ursprung ]
  12. 12. Kommentar Umschließende Sterne heben ein Wort hervor (*wort*), per _wort_ kann ein Wort unterstrichen werden. Um maschinelle und automatische Übertragung von Spamkommentaren zu verhindern, bitte die Zeichenfolge im dargestellten Bild in der Eingabemaske eintragen. Nur wenn die Zeichenfolge richtig eingegeben wurde, kann der Kommentar angenommen werden. Bitte beachten Sie, dass Ihr Browser Cookies unterstützen muss, um dieses Verfahren anzuwenden.  Hier die Zeichenfolge der Spamschutz­Grafik eintragen:  BBCode­Formatierung erlaubt   Daten merken?   Kommentar abschicken   Vorschau

×