Domanda

Se si dispone di due istanze di una stringa, e sono uguali, in Java che condivideranno la stessa memoria. Come è implementato sotto il cofano?

EDIT: La mia applicazione utilizza un gran numero di oggetti String, molti dei quali sono identici. Qual è il modo migliore per fare uso di Java String costante piscina, al fine di evitare la creazione di implementazione dei pesi mosca personalizzato?

È stato utile?

Soluzione

guardare il codice sorgente del java.lang.String (la fonte di tutta la Java API fa parte del JDK).

Per riassumere: A String avvolge una sottosequenza di un char[]. Questo supporto char[] non viene mai modificato. Questo si ottiene né perdite né catturare questa char[] di fuori della classe String. Tuttavia, diversi Strings possono condividere lo stesso char[] (vedi Attuazione String.substring).

C'è anche il meccanismo di internamento, come spiegato nelle altre risposte.

Altri suggerimenti

  

Se si dispone di due istanze di una stringa, e sono uguali, in Java che condivideranno la stessa memoria

Questo è in realtà non è vero al 100%.

Questo post del blog è una spiegazione decente del perché questo è così, e ciò che il stringa costante piscina è.

Le stringhe sono internati in Java, quindi non c'è davvero solo un oggetto String con riferimenti multipli (quando sono uguali, che non è sempre il caso). Vedi l'articolo java.net Tutto su intern () per maggiori dettagli.

C'è anche un buon esempio / spiegazione nella sezione 3.10.5 stringa letterali dei JLS che parla di quando le stringhe sono internati e quando saranno distinti.

Non è necessario vero. Esempio:

String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true

ma

String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false

Ora la seconda forma è scoraggiato. Alcuni (me compreso) pensare che String non dovrebbe nemmeno avere un costruttore pubblico. Una versione migliore di quanto sopra potrebbe essere:

String s1 = new String("hello").intern();
String s2 = new String("hello").intern();
System.out.println(s1 == s2); // true

Ovviamente non c'è bisogno di fare questo per un String costante. E 'illustrativo.

Il punto importante di questo è che se stai passato un String o ottenere uno da una funzione non si può fare affidamento sul String essere canonica . A canonica soddisfa Object questa uguaglianza:

a.equals(b) == b.equals(a) == (a == b)

per le istanze non null a, b, di un dato Class.

Per rispondere alla tua domanda modificato, Sun JVM ha un'opzione -XX:+StringCache, che a mia osservazione in grado di ridurre l'occupazione di memoria di un'applicazione pesante stringa in modo significativo.

In caso contrario, si ha la possibilità di internato le corde, ma vorrei essere attenti a questo. Le stringhe che sono molto grandi e non si fa riferimento sarà ancora possibile utilizzare la memoria per la vita della JVM.

Modifica (in risposta a un commento): ho scoperto che l'opzione StringCache da qui :

  

-XX:. + StringCache Abilita la memorizzazione nella cache di stringhe comunemente assegnati

Tom Hawtin descrive un certo tipo di caching per migliorare alcuni parametri di riferimento. La mia osservazione quando ho messo su idea era che l'occupazione di memoria (dopo una garbage collection completa) è andato fino in fondo sopra non averlo. E non è un parametro documentata, e può effettivamente essere solo di ottimizzazione per alcuni parametri di riferimento. La mia osservazione è che lo ha aiutato, ma non vorrei costruire un sistema importante basato su di esso.

Due cose da essere attenti a:

  1. Non utilizzare il costruttore new String("abc"), basta utilizzare il "abc" letterale.
  2. intern ( ) metodo in classe String. Soprattutto quando concatenazione di stringhe insieme o per la conversione char serie / array di byte / etc in una stringa.

intern() restituisce sempre stringhe che vengono messi in comune.

Se le stringhe identiche provengono da un insieme fisso di valori possibili, poi un type-safe Enumeration è ciò che si vuole qui. Non solo si riduce il valore della stringa, ma renderà per una più solida applicazione. Tutta la tua app saprà Questa stringa ha la semantica collegato ad esso, forse anche alcuni metodi di convenienza.

I miei ottimizzazioni preferiti sono sempre quelli che possono essere difesi come rendere il codice migliore , non solo più veloce. E 9 volte su 10, la sostituzione di una stringa con un tipo concreto porta a codice più corretto e di auto-documentazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top