klassen auf dem stack erzeugen ohne new


  • Mod

    Sovok schrieb:

    geht sowas in java?

    1. Du kannst es nicht von Hand machen.
    2. AFAIK macht die JVM das auch nicht automatisch.
    3. AFAIK sind allerdings Optimierungen im Gespräch, nach denen die JVM das in bestimmten Situationen machen würde. Also vor allem bei Objekten, die nur einen sehr kleinen Gültigkeitsbereich haben.


  • Mod

    Sovok schrieb:

    weil bei mir der GC am rad dreht wenn ich am laufenden band neue StringTokenizer instanzen erzeug um strings durchzujagen

    normalerweise lös ich sowas indem ich die instanzen wiederverwende aber beim StringTokenizer geht das nich

    Kannst Du mal beispielhaft angeben, wieviele Du da so erzeugst, wie groß die Strings sind und so weiter? Ich würde da gerne eine Vorstellung entwickeln. Und: Hast Du die aktivität des GCs mit einem Profiler ausgemessen oder ist das nur eine Vermutung?



  • Gregor schrieb:

    Kannst Du mal beispielhaft angeben, wieviele Du da so erzeugst, wie groß die Strings sind und so weiter? Ich würde da gerne eine Vorstellung entwickeln. Und: Hast Du die aktivität des GCs mit einem Profiler ausgemessen oder ist das nur eine Vermutung?

    Muss dazu sagen dass ich nich von Desktop Java spreche sondern von Android und
    die Aktivität des GC seh ich direkt in der debugging konsole (logcat).
    Ca. 200-400ms alle paar sekunden, dadurch stockt das komplette Handy immer mal wieder.
    Die Strings sind ein kontinuierlicher Datenstrom von einem Kommandozeilen Befehl der über stdin reinkommt. Dabei lässt sich die Menge der Daten beliebig skalieren aber je mehr desto besser bzw. desto genauer ist das Ergebnis.

    @Gregor hast du schonmal was mit JNI gemacht? Was ist die beste Möglichkeit um große Gruppen von Daten im 1-2KB Bereich (ints und ascii strings) mit einem Schlag von C++ nach Java zu transferieren mit möglichst wenig Overhead?



  • Sovok schrieb:

    +fricky schrieb:

    also warum sollte man sowas tun? 🙂

    weil bei mir der GC am rad dreht wenn ich am laufenden band neue StringTokenizer instanzen erzeug um strings durchzujagen

    normalerweise lös ich sowas indem ich die instanzen wiederverwende aber beim StringTokenizer geht das nich

    werds wohl in c++ schreiben und mit JNI anbinden müssen

    Wieso benutzt du auch StringTokenizer?
    http://java.sun.com/j2se/1.4.2/docs/api/java/util/StringTokenizer.html

    StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.

    Edit: Kenn mich mit Android nicht aus, aber wenn die SDK auch java.util.regex hat wuerde ich lieber das nutzen.



  • soweit hab ichs mir nich durchgelesen 🤡

    danke werds mal testen



  • DEvent schrieb:

    StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.

    String.split() ist nicht schneller (eher noch langsamer), kann aber regex-gesteuert arbeiten.
    @OP: wenn das löschen alter StringTokenizers durch den GC wirklich die bremse ist, dann programmier dir doch 'nen eigenen tokenizer, der nicht jedesmal mit new angelegt werden muss.
    🙂



  • Ist doch eingentlich nur ne einfache Schleife.



  • nicht unbedingt wenn man den garbage collector auf 0 neue instanzen drücken will ohne ineffizient zu werden

    in c++ wärs für mich kein problem aber bei java weiss ich manchmal nich was da im hintergrund wirklich passiert



  • Sovok schrieb:

    in c++ wärs für mich kein problem aber bei java weiss ich manchmal nich was da im hintergrund wirklich passiert

    ist es auch nicht, da nimmste einfach 'strtok'. aber für sowas eigens ein JNI-modul zu basteln und die plattformunabhängigkeit zu verlieren, halte ich für übertrieben. bestimmt geht's auch in 'pure java' schnell genug.
    🙂



  • 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.
    🙂


Anmelden zum Antworten