klassen auf dem stack erzeugen ohne new



  • Normalerweise ist es keine gute Idee, dem GC helfen zu wollen, indem man Objekte wieder verwendet. Dadurch wird die Sache eher langsamer. Wie das bei Android aus sieht weiß ich nicht.



  • tfa schrieb:

    Normalerweise ist es keine gute Idee, dem GC helfen zu wollen, indem man Objekte wieder verwendet. Dadurch wird die Sache eher langsamer. Wie das bei Android aus sieht weiß ich nicht.

    Auf Android ist das nach meiner Erfahrung definitiv anders.
    Allerdings hätt ich noch gern eine Begründung von dir warum das keine gute Idee ist.

    Abgesehen davon geht es nicht darum dem GC zu helfen, sondern du verhindern dass er Zeit stiehlt.



  • Moderne GC-Implementierungen arbeiten mit generationellen Verfahren. Dabei nutzt man aus, dass die meisten Objekte nur sehr kurze Zeit existieren (z.B. innerhalb eines Scopes). Solche Objekte können dann unverzüglich freigegeben werden, ohne, dass es GC noch einen großen Aufwand treiben müsste, sie zu finden. Der Aufwand hierfür ist praktisch null, so kann eine automatische Speicherverwaltung sogar schneller sein, als ein explizites delete.
    Das funktioniert aber nur, wenn die Objekte kurzlebig sind. Bei langlebigen, vielleicht sogar gepoolten Objekten funktioniert das nicht, und der GC stiehlt dir Zeit.
    Wie gesagt, keine Ahnung wie der GC bei der Android-VM implementiert ist...
    JNI ist jedenfalls höchstwahrscheinlich keine Lösung. Der Aufrufoverhead ist zu Groß - von den Problemen beim Datenaustausch ganz zu schweigen.



  • Hört sich interessant an :).
    Hast du irgendwo eine "exakte" Definition von kurzlebig sodass ich aus dem Code vorhersagen kann welche Instanzen an den GC gehen und welche nicht?

    JNI is für mich eh vorerst gestorben weil laut Google das Native Development Kit für Android erst Mitte des Jahres rauskommt.



  • Nein, kann ich nicht. Das sind Interna der GC-Implementierung. Du kannst ja mal deinen problematischen Code zeigen, vielleicht kann man da was sehen.



  • glaub nicht, dass das nur am StringTokenizers liegt. Wahrscheinlich hat der GC viel mehr mit den ganzen Strings die du damit erzeugst zu tun. Strings sind ja auch noch immutable, es wird also bei jeder Änderung des Strings ein neuer erzeugt.



  • Ja ich bau mir das ganze grad von hand mit nem einzelnen char buffer

    gibts in java ne funktion der man sagen kann nimm char 25-30 und mach mir n integer drauß?
    so wie atoi in c
    will vermeiden die chars vorher in nen string konvertieren zu müssn



  • Sovok schrieb:

    will vermeiden die chars vorher in nen string konvertieren zu müssn

    such mal nach 'parseInt' und 'java.util.Scanner'. müsste auch mit 'CharSequence' oder 'StringBuffer' gehen.
    🙂



  • da hab ich nix gefunden

    Integer.parseInt gibts nur für String und der Scanner scheint nur zu gehn wenn man ihn für den kompletten content benutzt

    noch andere ideen?



  • auch selber schreiben. ist ja nicht so schwer, gibt wahrscheinlich auch genug beispiele im netz



  • Sovok schrieb:

    Integer.parseInt gibts nur für String und der Scanner scheint nur zu gehn wenn man ihn für den kompletten content benutzt

    wie sieht den dein content aus? 'char' in Java ist 16-bittig (für unicode). falls du 1-byte pro zeichen hast, ist vielleicht besser, mit dem Java typ 'byte[]' zu arbeiten.
    🙂



  • StringBuilder -> richig benutzt: effizient

    StringBuffer -> das selbe, aber dazu noch "thread safe"

    zum gc: die falle ist, dass wenn man sachen, die man nicht mehr braucht nicht gleich "nullt" und somit die objekte noch rumliegen. wenn dann noch diverse calls kommen, während das objekt rumliegt, kann es passieren, dass zwischenzeitlich der gc aktiv wird und das besagte objekt das aufräumen überlebt und damit von generation0 zu generation1 befördert wird. hierdurch wird es noch schwerer, das ding wieder los zu werden.

    also es sollte eigentlich schon helfen, referenzen, wenn man weiss, dass man sie nicht mehr braucht, direkt null zu setzen. ansonsten kann man auch mit System.gc(); die garbage collection erzwingen, wenn es zeitlich gerade passt.

    hauptspeicherfragmentierung könnte auch ein grund für langsame gc sein, wie noch vieles weitere. i.d.r ist nicht der gc sondernder programmierer schuld. im zweifelsfall nochmal nachgoogeln, wie der gc wirklich funktioniert 😉



  • jule37 schrieb:

    ansonsten kann man auch mit System.gc(); die garbage collection erzwingen, wenn es zeitlich gerade passt.

    Nein, nein, nein. Kann man nicht! Und soll man auch nicht.
    http://java.sun.com/docs/hotspot/HotSpotFAQ.html#gc_pooling



  • okay, dann das nicht. wieder was gelernt. aber der rest müsste stimmen 😛



  • jule37 schrieb:

    StringBuilder -> richig benutzt: effizient

    StringBuffer -> das selbe, aber dazu noch "thread safe"

    Und was bringt ein StringBuffer, wenn man den String zerlegen will?



  • tfa schrieb:

    jule37 schrieb:

    ansonsten kann man auch mit System.gc(); die garbage collection erzwingen, wenn es zeitlich gerade passt.

    Nein, nein, nein. Kann man nicht! Und soll man auch nicht.
    http://java.sun.com/docs/hotspot/HotSpotFAQ.html#gc_pooling

    gilt halt wieder nicht für embedded systeme wie android
    hab vorher ein spiel mit einigen animationen programmiert

    ohne pooling und System.gc() hats da regelmäßig geruckelt weil der
    gc wenn er grad bock hatte reingesprungen is
    mit pooling und System.gc() zum richtigen zeitpunkt z.b. direkt nach ner user eingabe liefen die animationen einwandfrei flüssig



  • jule37 schrieb:

    StringBuilder -> richig benutzt: effizient
    StringBuffer -> das selbe, aber dazu noch "thread safe"

    die beiden mag ich insofern nich weil man um den string zu benutzen erst wieder nen immutable string objekt erzeugen muss

    hab aber rausgefunden dass die views in android auch mit CharBuffer arbeiten können... damit kann ich meine chars direkt aus dem hauptbuffer in die kleineren charbuffer kopiern und brauch keine extra allokation

    für die ints hab ich jetzt ne eigene konvertierungsfunktion von char nach int über den ascii wert geschrieben wobei jede stelle mit ner zehnerpotenz multipliziert wird (bin offen für effizientere vorschläge)... direkt mit byte zu arbeiten wär zwar noch besser weil damit ein kompletter kopiervorgang wegfällt aber damit kann CharBuffer wieder nich umgehn und java is ja leider typesafe ^^ (nich ernst nehmen) und hat keine 8 bit chars


Anmelden zum Antworten