Was bedeutet es, dass Java keine direkten Speicher- und Hardwarezugriffe kennt?

... komplette Frage anzeigen

3 Antworten

Programme welche in Java geschrieben werden haben keinen direkten Speicher- und Hardwarezugriff weil sie nicht direkt auf der Hardware laufen. 

Das Java Runtime Environment (JRE) führt die Javaprogramme aus, also im Prinzip wird während das Programm läuft der Javacode durch JRE auf die CPU umgesetzt. Dadurch kann ein Javaprogramm unabhängig von Architektur und System auf vielen verschiedenen System ausgeführt werden.

Anders als bei nativen Sprachen (C/C++ beispielsweise) läuft das Programm dadurch aber nie direkt auf dem Prozessor und kann somit auch niemals direkt die Hardware ansprechen, weil zwischen Hardware und Software noch eine Softwareebenen liegt, welche die Schnittstelle darstellt.

Gruß Lolwis111

Kommentar von joka22061990
17.01.2016, 12:12

Danke für die schnelle Antwort :)

2

Hallo!

"Sicher" heist in diesem Zusammenhang, dass es (nach der Entwicklerphase) nicht oft zu Programmabstürzen kommt, wegen Zugriff auf eine, z.B. dem OS zugeordnete Speicherzelle kommt.

Mir fällt da erst mal der alte C64 ein, um Spiele mit Farben und bewegte Objekt darzustellen, waren Befehle wie Push(0xA3,94321) nötig, wobei 94321 eine Speicherzelle bedeutet und 0xA3 ein HexWert ist. Diese wurde damit überschrieben.

Dabei war auch zu beachten (das oben war wohl ungültig, da Speicherzelle ungerade) wieviel Byte der einzulesende Wert hat.

Sonst gilt mit Einschränkungen, für die Verständlichkeit, die Antwort von Lolwis.

Gruß

Kommentar von mepeisen
17.01.2016, 12:55

das oben war wohl ungültig, da Speicherzelle ungerade

Nö. C64 war 8bit ;-)

Allerdings hatte der nur 64k Speicher ;-)

0

Das bedeutet, dass ein Programmierer vor sich selbst geschützt ist, da er durch Programmierfehler nicht einfach wild im Speicher rumpfuschen kann, was oftmals dazu führt, dass Daten überschrieben werden und somit kaputt gehen. :)

Auf der einen Seite ist das zwar praktisch, aber auf der anderen Seite verhindert das z. B., dass man sichere und effiziente Datenbankengines in reinem Java schreiben kann, da man mit Java kaum Kontrolle über die verschiedenen Caches und Puffer hat, und z. B. die Schreibzugriffe auf ein Speichermedium kaum kontrollieren kann.

Bei Java sieht das Ganze so aus:

User Cache* => Java Cache** => Laufzeit Cache*** => Dateisystem Cache*** => Kernel Cache**** => Controller Cache**** => Geräte Cache**** => Platte

... wobei jeder Lese-/Schreibvorgang durch all diese Schichten durch muss, und es dazwischen sogar noch mehr Puffer geben kann (bzw. in 99% aller modernen Betriebssysteme geben WIRD).

* bedeutet optional

** bedeutet in Java selbst leicht deaktivierbar

*** bedeutet nicht innerhalb von Java deaktivierbar

**** bedeutet nur mit Kopfständen deaktivierbar

Wenn man bei einem Schreibvorgang auf die Bestätigung warten möchte, bedeutet das außerdem, dass der Aufruf durch all diese Schichten hin, UND auch wieder zurück muss. Das oft sogar noch mehr als 13 Schichten!

Bei einem C-Programm, mit Konfiguration durch ioctl() und posix_advise() sieht das dann so aus:

User Cache* => Platte

Das ist auch der Grund, warum viele Datenbanken direkt in C oder C++ geschrieben sind, und am Dateisystem vorbei direkt auf der Platte arbeiten, wobei sie sich selbst ums Caching kümmern. Anders ist so eine hohe IO-Performanz und Fehlertoleranz nicht zu erreichen. Du kannst ja mal MySQL mit einer "richtigen" Oracle Datenbank vergleichen ... das ist ein Unterschied wie Tag und Nacht! :)

Hinzu kommt, dass man Read-Ahead mit Java schlecht beeinflussen kann, und wenn du nur einen 512 Byte Sektor lesen willst (weil du dich selber um effizientes Caching kümmerst), werden stattdessen gleich 128 KB eingelesen, was zwar normalerweise vor allem bei Streams sehr effizient ist, aber z. B. beim angesprochenen Problem einer Datenbank-Engine ein absolutes K.O. Kriterium ist.

Man kann zwar durch Kernel-, Boot-, Mount- und teilweise sogar JVM-Einstellungen viele dieser Probleme lösen, aber nicht alle. Und für den ganzen Klimmbimm, den man bei einem reinen C-Programm mit wenigen Zeilen Code und ein paar Syscalls erledigen kann, muss man bei Java wirklich auf ein genau angepasstes und händisch optimiertes System achten, um performant zu bleiben. Der Aufwand ist bei Java verglichen mit C enorm.

Allerdings ist Java wesentlich mehr High-Level als C und damit lässt sich vieles komfortabler und auch sicherer entwickeln. Für Low-Level Sachen wie Treiber nimmt man natürlich C, aber für irgendwelche Serveranwendungen wird oft Java vorgezogen.

Und um nochmal auf die Datenbank-Engines zurück zu kommen: In den meisten Fällen kommt es nicht so sehr auf Höchstperformanz an, sondern auf ganz andere Dinge. Die meisten Websites dürften keinen Unterschied bemerken, ob sie HSQLDB oder Oracle einsetzen, da sie sowieso niemals in den kritischen Anfragebereich kommen werden.

(Allerdings sieht man bei GF sehr gut, was passiert, wenn man sich für das falsche DB-System entscheidet ... "Steht da jemand auf der Leitung?")

Fazit: Du hast mit Java wesentlich weniger Kontrolle über die Hardware, und allem was dazu gehört (Caches, Prozessorkerne, Low-Level-Schnittstellen, usw.), aaaaaber in den aller meisten Fällen braucht man das auch gar nicht! Es ist entweder unnötig, oder man benutzt eine Bibliothek (oftmals in C/C++ geschrieben), die einem diese Aufgaben abnimmt.

Von daher ist Java trotz "Low-Level-Mangel" für die meisten Aufgaben sehr gut geeignet, um diese elegant zu erledigen! :)

Der Einsatzzweck einer Sprache hängt immer von der Aufgabe ab, und die Wichtigkeit zu hoher Performanz wird oftmals überschätzt! Wenn eine Datenbank sowieso nur zu 15% ausgelastet ist, dann nützt es nichts, sich anzustrengen, und auch noch die letzten 3% Leistung rauszukitzeln. ;)

Kommentar von TeeTier
17.01.2016, 14:39

PS: Davon abgesehen ist meistens nicht die Implementierung des Datenbanksystems der Flaschenhals, sondern das eigentliche Datenbank-Design! Wer nicht gut mit Schlüsseln umgehen kann, dem nützt auch eine High-Performance-DB nichts mehr. :)

0

Was möchtest Du wissen?