2013-04-17 14 views
11

Dies könnte eine dumme Frage sein (oder mich einfach nur dumm aussehen :)), aber ich würde daran interessiert sein, wie mit langen String-Objekten im Rahmen von kurzlebigen Objekten zu arbeiten.lange statische Strings in kurzlebigen Objekten

Denken Sie an lange SQL-Abfragen in Cron-Job oder anonyme, Befehl oder Funktion-ähnliche Klassen. Diese sind sehr kurzlebige Klassen und werden diese langen Strings sogar die meiste Zeit ihres Lebens benutzen. Was ist besser? Um eine Zeichenkette inline zu konstruieren und sie mit der Instanz zu sammeln, oder sie trotzdem statisch endgültig zu machen und sie im Speicher nutzlos zu lassen, bis zur nächsten Instanziierung der Klassen?

+0

Ist die Abfrage unterschiedlich für jeden der kurzlebigen Objekte? –

+0

Hängt davon ab, wie oft diese kurzlebigen Klassen erstellt werden und ob die Abfragen alle gleich sind –

+0

Nein, alle gleich für alle Instanzen – user1405469

Antwort

8

Nun, es gibt nur so viel Kontrolle darüber, was mit dem String passiert.

Auch wenn Sie es inline erstellen, wird diese Zeichenfolge höchstwahrscheinlich zum String-Konstantenpool der JVM hinzugefügt und bei der erneuten Deklaration wiederverwendet. In der Praxis werden Sie wahrscheinlich dieselbe Zeichenfolge wiederverwenden Objekt in beide Richtungen.

Sofern der String so groß ist, dass es einen Einfluss auf die Leistung Ihrer Anwendung hat, würde ich nicht darum kümmern und die Option wählen, die besser lesbar mir schien.

Wenn dieser String nur an einem bestimmten Punkt des Codes verwendet wird, würde ich ihn innerhalb einer Methode als Inline deklarieren. Ich bevorzuge es, meine Variablen im kleinsten Rahmen zu haben, aber die Meinungen können variieren. Wenn es überhaupt keine Änderung gibt und es in Ihrem speziellen Anwendungsfall sinnvoll erscheint, deklarieren Sie die Zeichenfolge unbedingt als statisch. Ich bezweifle, dass dies Auswirkungen auf die Leistung hat.

2

String-Konstanten gehen in den Konstantenpool einer Klasse und können nicht wegoptimiert werden, d. H. Sie werden ausreichend gut behandelt.

Erstellen lange Strings nicht statisch. Für SQL-Verwendung vorbereitete Anweisungen mit einem ? Platzhalter. Dasselbe gilt für Zeichenfolgen mit Platzhaltern: Verwenden Sie MessageFormat.

Um explizit zu sein. Die folgende kostet nichts Extra:

static final String s = "... long string ..."; 
+0

Ich mochte den ersten und letzten Teil Ihres Kommentars . Ihre vorbereiteten Aussagen- und Nachrichtenformat-Ideen treffen in meiner Situation nicht zu, da diese Objekte/Cronjobs wirklich nur ein einzelnes, aber langes SQL-Update ausführen und damit erledigt werden. Keine Parameter, nichts. Obwohl Sie vorbereitete Anweisungen und Zeichenfolgen mit Platzhaltern verwenden, müssen Sie diese langen Zeichenfolgen dennoch irgendwie speichern :). – user1405469

-2

Wenn der Speicher verbleibende begrenzte JVM ist wird in der Regel tun zul gen Raum Reinigung und Entladen nicht genutzt/nicht referenzierte Klassen. Also mit den langen Strings als statische Variable wird nicht viel schaden meiner Meinung nach

+1

-1.Classes werden nicht so entladen. – Lokesh

+0

Sie können mehr über Speicherbereinigung in diesem Blog lesen http://www.javaworld.com/jw-06-1998/jw-06-techniques.html – AurA

+0

@loki haben Sie "CMSClassUnloadingEnabled" JVM-Option oder Blick auf Speicherauslastung verwendet über JConsole usw. einer Anwendung? –

-2

Wenn Sie Ihre Strings fühlen viel Speicher belegen kann dann machen nicht sie statisch oder erklären sie wörtliche mit String. Da diese beiden in permgen Raum gespeichert werden und fast immer Müll gesammelt werden [es gibt Chance, aber schlank, Statik kann nie Müll gesammelt werden, wenn Sie nicht Ihren eigenen Klassenlader erstellt haben]. So erstellen String Operator new damit, dass im Heap erstellt werden und leicht Müll gesammelt werden, dh

String str = new String("long string"); 

EDIT:

Wie Strings gespeichert sind: http://www.ntu.edu.sg/home/ehchua/programming/java/J3d_String.html

EDIT:

Es gibt eine lange Diskussion darüber, wie der neue String funktioniert. Argument präsentiert ist, dass neue String 2 Objekte eins im Heap und eins im Pool erstellen wird. Das ist falsch, es ist standardmäßig nicht richtig und Sie können Java dazu zwingen, dies zu tun, indem Sie die interne Methode aufrufen.Um mein Argument zu unterstützen finden Sie die javadoc von Strin Klasse für intern Methode:

intern

public String intern() Gibt eine kanonische Darstellung für das String-Objekt. Ein anfangs leerer String-Pool wird privat von der Klasse String verwaltet. Wenn die interne Methode aufgerufen wird und der Pool bereits eine Zeichenkette enthält, die diesem String-Objekt entspricht, wie durch die Methode equals (Object) bestimmt, wird die Zeichenfolge aus dem Pool zurückgegeben. Andernfalls wird dieses String-Objekt zum Pool hinzugefügt und eine Referenz auf dieses Objekt String zurückgegeben.

Daraus folgt, dass für zwei beliebige Strings s und t, s.intern() == t.intern() ist wahr, wenn und nur wenn s.equals (t) wahr ist.

Alle literalen Zeichenfolgen und konstanten Konstantenausdrücke sind Interned. String-Literale wird in §3.10.5 der Java-Sprache Spezifikation definiert

Wie von oben doc zu sehen, dass, wenn neuer String immer ein Objekt im Pool erstellt dann intern Methode völlig nutzlos sein wird !! Auch logisch ergibt es keinen Sinn.

EDIT:

auch die Antwort für diesen Beitrag lesen: String pool creating two string objects for same String in Java

+0

In diesem Fall könnte str möglicherweise Müll gesammelt werden, aber "long string" ist in permgen gespeichert, nicht wahr? – mjaggard

+0

Also du meinst zu sagen, die ganze Zeichenfolge zu Permgen gehen, ob Sie Literal erstellen oder neue verwenden? Was ist der Gebrauch von intern() Methode dann? Was brauchst du wirklich, um String mit new zu erstellen? – Lokesh

+0

@mjaggard: Bitte begründen Sie Ihr Argument oder entfernen Sie den Downvote – Lokesh

Verwandte Themen