Warum ist Java eigentlich so lahm und speicherfressend?



  • otze schrieb:

    in dem moment, wo der bytecode in hardware direkt ausgeführt wird,geht die hardware unabhängigkeit verloren, und wenn die erstmal weg ist,dann fangen ein paar neue probleme an

    naja. nicht gans.
    sagen wir mal, java muß grundsätlich auf jeder maschine ne vm haben.
    sagen wir auch, AMD baut nen ganz flotten prozessor, der bytecode direkt ausführen kann.
    würde das nicht einfach nur heißen, daß die vm sehr platt und einfach sein wird?
    sagen wir auch, daß immer gejitted wird. naja, jitten für den hypothetischen bytecodeprozessor geht mit memcpy.
    dann kommt meinetwegen ein update des bytecodestandards und der prozessor wird nicht geupdated. uih, jetzt muß der jitter aber arbeiten. halt den neuen befehl immer umsetzen, den rest memcpyen.
    mir klingt das gar nicht so schlecht.



  • habefrage schrieb:

    Eigentlich könnte es durch JIT-Compilation doch schneller sein. Und dass die VM auch Speicher braucht, ist klar. Aber warum ist dann z.B. Eclipse so ein riesen Speicherfresser?

    trifft nicht nur eclipse. aber der grund ist mir ein rätsel. immer wieder mal gab es nen performance-vergleich zwischen c++ und java mit kleinen test-programmen. immer wieder war der unterschied gering. manchmal gewann java, manchmal c++. bei jedem programm konnte c++ knapp gewinnen, aber oft nur, indem man auch die winapi bemüht (z.B. weil cout lahm ist) und manchmal auch eine oder zwei wochen dran bastelt.
    und ich kann versichern, daß einige leute verbissen versucht haben, stellen zu finden, wo java echt schneller oder wo c++ echt schneller ist. bisher gabs nix. höchstens mal nen faktor 10 (da war java mal fett schneller, das ließ sich aber beheben durch einspielen des stlfix').
    daß manche java-apps echt verschwenderisch sind, läßt sich aber nicht von der hand weisen. sind es nur historische gründe, alte libs und so sachen? ich hab keinbe ahnung und würde es auch gerne erfahren.

    habefrage schrieb:

    Bitte um sachliche Antworten.

    ich kann nicht sachlich sein. sorry.



  • Solche Prozessoren gibt es ja schon für Mainframes(andere sind mir nicht bekannt). Z. B. http://www.heise.de/newsticker/result.xhtml?url=/newsticker/meldung/46362



  • volkard schrieb:

    daß manche java-apps echt verschwenderisch sind, läßt sich aber nicht von der hand weisen. sind es nur historische gründe, alte libs und so sachen? ich hab keinbe ahnung und würde es auch gerne erfahren.

    IMHO kann das auch daran liegen, weil es VMs für sehr viele verschiedene Plattformen gibt und die libs erst nach und nach effizient implementiert werden. Swing ist doch ein schönes Beispiel dafür, mit jeder Version wird es ein wenig schneller. Das wichtigste ist ja prinzipiell schon, dass erst mal alle Funktionalität da ist, optimieren kann man dann immer noch.

    Da hat es Microsoft mit seinem .Net Framework natürlich leicht, die haben keine großen Probleme damit, ihre Windows Forms gleich beim ersten mal effizient zu implementieren. Bei der gigantischen Vielzahl an Plattformen, die die unterstützen müssen, würde ich das auch beim ersten mal gleich gescheit machen. Dumm sind sie aber auch nicht, z.B. hat Microsoft als erste Firma das JIT-compiling für die MS VM eingeführt, bis dahin hat die VM nur interpretiert.

    habefrage schrieb:

    Bitte um sachliche Antworten.

    ich kann nicht sachlich sein. sorry.

    roflmao.



  • SnorreDev schrieb:

    FinalBlackout schrieb:

    Wozu denn der manuelle GC-Aufruf? Der GC wird sie schon löschen, wenn grad Speicher gebraucht wird oder wenn der Anwendung grad langweilig ist. 😃

    Ich weiss - ihr redet von einer normalen PC Plattform, aber auf Devices mit begraenzten Ressourcen ist dies unerlaesslich. Die GC denkt nicht wirklich immer mit, und loescht, und schon ist die App gecrashed.

    Kannst du das bitte näher ausführen? Ich halte das nicht für nötig, aus Gründen der Speicherknappheit den GC manuell aufzurufen. Der wird schon aktiv, wenn der Heap voll wird. Und das er Objekte löscht, die noch gebraucht werden, halte ich für ein ziemliches Gerücht.
    Als einzigen sinnvollen Grund, den GC manuell aufzurufen könnte ich mir Performancegründe vorstellen. Wenn ich weiss, dass ich gerade eine Menge Objekte nicht mehr referenziere und jetzt gerade die Performance nicht ganz so relevant ist, dann könnte es sich vielleicht lohnen, den GC schnell alles fressen zu lassen, bevor es später wieder ungünstig wird und er mitten in einem performancekritischen Programmteil anspringt.
    Oder vielleicht ist es auch sinnvoll, um ein paar finalizer anlaufen zu lassen.



  • Optimizer schrieb:

    Oder vielleicht ist es auch sinnvoll, um ein paar finalizer anlaufen zu lassen.

    Für was nutzt du finalizer?



  • Für nichts. War nur ein Gedankengang, ich könnte es mir vorstellen um unmanaged Resourcen freizugeben, wie z.B. ne Socket-Verbindung.
    Naja, ich bin darauf im Moment nicht angewiesen, ich sehe es eher als zusätzliche Sicherheit.



  • volkard schrieb:

    trifft nicht nur eclipse. aber der grund ist mir ein rätsel. immer wieder mal gab es nen performance-vergleich zwischen c++ und java mit kleinen test-programmen. immer wieder war der unterschied gering. manchmal gewann java, manchmal c++. bei jedem programm konnte c++ knapp gewinnen, aber oft nur, indem man auch die winapi bemüht (z.B. weil cout lahm ist) und manchmal auch eine oder zwei wochen dran bastelt.
    und ich kann versichern, daß einige leute verbissen versucht haben, stellen zu finden, wo java echt schneller oder wo c++ echt schneller ist. bisher gabs nix. höchstens mal nen faktor 10 (da war java mal fett schneller, das ließ sich aber beheben durch einspielen des stlfix').
    daß manche java-apps echt verschwenderisch sind, läßt sich aber nicht von der hand weisen. sind es nur historische gründe, alte libs und so sachen? ich hab keinbe ahnung und würde es auch gerne erfahren.

    Die nicht sehr resourcenschonenden Java-Programme haben IMHO verschiedene Gründe.

    Ein Teil liegt an schlechten Stellen der Standardbibliothek oder an einer schlechten Verwendung dieser.

    Ein Teil liegt an Unwissen.

    Ein Teil liegt an der Sprache selbst, bzw. dessen Implementation. In Java bringt jedes Objekt einen gewissen Overhead mit sich, der so in einigen anderen Sprachen nicht vorhanden ist. Beispiel: Ein int ist 4 Byte groß. Wenn man stattdessen einen Integer nimmt, also den entsprechenden Wrappertyp, dann hat man es plötzlich mit 16 Byte zu tun (AFAIK). Da die meisten Objekte sehr klein sind, macht sich dieser Overhead auch entsprechend bemerkbar. Deshalb gehört es zum Beispiel auch zu den üblichen Optimierungsmethoden in Java, viele (nur) gleiche Objekte zu vermeiden und stattdessen viele identische Objekte anzustreben. Dies ist IMHO ein Punkt, den viele nicht stark genug beachten, bzw. dessen sich viele nicht bewußt sind.



  • Optimizer schrieb:

    SnorreDev schrieb:

    FinalBlackout schrieb:

    Wozu denn der manuelle GC-Aufruf? Der GC wird sie schon löschen, wenn grad Speicher gebraucht wird oder wenn der Anwendung grad langweilig ist. 😃

    Ich weiss - ihr redet von einer normalen PC Plattform, aber auf Devices mit begraenzten Ressourcen ist dies unerlaesslich. Die GC denkt nicht wirklich immer mit, und loescht, und schon ist die App gecrashed.

    Kannst du das bitte näher ausführen? Ich halte das nicht für nötig, aus Gründen der Speicherknappheit den GC manuell aufzurufen. Der wird schon aktiv, wenn der Heap voll wird. Und das er Objekte löscht, die noch gebraucht werden, halte ich für ein ziemliches Gerücht.
    Als einzigen sinnvollen Grund, den GC manuell aufzurufen könnte ich mir Performancegründe vorstellen. Wenn ich weiss, dass ich gerade eine Menge Objekte nicht mehr referenziere und jetzt gerade die Performance nicht ganz so relevant ist, dann könnte es sich vielleicht lohnen, den GC schnell alles fressen zu lassen, bevor es später wieder ungünstig wird und er mitten in einem performancekritischen Programmteil anspringt.
    Oder vielleicht ist es auch sinnvoll, um ein paar finalizer anlaufen zu lassen.

    Vielleicht hatte ich mich falsch ausgedruckt, die GC loescht in dem Fall nicht unbedingt was warscheinlich in einer teilweise auf Hardwareseite schlecht implementieten GC liegt, was dir z.B. im Falle eines Image.createImage(size_x,size_y) schon mal eine OutOfMemoryException um die Ohren schmeissen kann. Nicht abgefangen ( aus Platzgruenden des .jar files in eine release Version ) ploeppt dann dieses Fenster mit der Exception auf, und du bist wieder soweit wie vorher.
    Bei der Performance trifft das schon zu was du gesagt hast - bei unkritischen Stellen schnell mal lehren, bevor nachher etwas ruckelt.



  • Optimizer schrieb:

    Für nichts. War nur ein Gedankengang, ich könnte es mir vorstellen um unmanaged Resourcen freizugeben, wie z.B. ne Socket-Verbindung.
    Naja, ich bin darauf im Moment nicht angewiesen, ich sehe es eher als zusätzliche Sicherheit.

    Ja, genau das ist auch der einzige sinnvolle Verwendungszweck für finalizer: Zusätzliche Sicherheit (z.B. bei der Freigabe von Resourcen).


Anmelden zum Antworten