のUUID(とも文字列)は自動的に重複排除されません。新しく作成されたUUIDはユニークでなければならないので、一般的には悪い考えです。共有は機能しません。
あなたがインターンの文字列を参照する場合は、JVMは、例えば、特定の場合には、文字列を共有することは事実である:
String x = "ab";
String y = "a" + "b";
assert x == y; // references are identical (x and y are shared)
これらは文字列である、しかし、コンパイル時に解決することができます。実行時に文字列またはUUIDを作成すると、常に新しいオブジェクトが作成されます。
あなたの質問では、別のシナリオを説明します。ここでは、データベースからUUIDを読み込みます。データに依存して、UUIDを共有する良い機会があるかもしれないし、存在しないかもしれない(例えば、UUIDが主キーとして使用されている場合)。
id | name | country
1 | A | <UUID-1>
2 | B | <UUID-1>
3 | C | <UUID-2>
4 | D | <UUID-1>
5 | E | <UUID-1>
(一般的には、あなたが同じ値のコピーを受け取ります。データベースまたはネットワークからUUIDを読むとき、あなたはのUUIDが重複除外されると仮定することができないことに注意してください。)
したがって、あなたのデータが上記のように見える場合、UUIDの共有は理にかなっています。しかし、それはメモリの使用量を減らすでしょうか?
UUIDは、2つのlong
変数を持つオブジェクトです。 64ビットJVMでは、32バイトを要します。あなたがUUIDを共有している場合は、一度32バイトを支払うだけで、その後は8バイトしか支払われません。 compressed pointersを使用すると、参照は4バイトに収まります。
このゲインは十分ですか?それはあなたの特定のアプリケーションに依存します。一般的に、私はUUIDを共有しません。しかし、私はUUIDの共有が本当に改善されたアプリケーションに取り組んできました。メモリ使用量を削減することは重要であり、完全なオブジェクトから参照への削減は改善されました。
このように言えば、この種の最適化はめったに必要ありません。大雑把に言えば、UUIDが大量に共有され、すべてのコストでメモリを削減する必要がある場合にのみ、私はそれを実行します。さもなければ、それらを重複排除するCPUのオーバーヘッドとコードの余分な複雑さはしばしばそれに値するものではなく、悪い場合にはアプリケーションの速度を低下させる可能性があります。
重複排除する場合はどうすればよいですか? String#intern
のような組み込み関数はありませんが、重複排除するマップを手動で作成できます。グローバルに重複排除するか現在の関数呼び出しでローカルにのみ重複排除するかによって、ConcurrentHashMap
または単に(非同期の)HashMap
を使用できます。あなたの質問に直接関連サイドノート、ないよう
それは文字列のAPIの一部であるとして、私はString#intern
を述べました。しかし、それを使用することを強くお勧めします。それはa huge performance bottleneckです。重複排除を自分で行うことは、大幅に高速になります。
実際にプログラムでRAMの使用が問題になっていますか? – bcsb1001
[grepcodeのソースコード](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/UUID.java#UUID)を見るとすでに存在する同等のUUIDを探す試みは何も見ないでください。インスタンスあたりの状態もほとんどありません。 –
私が知っていることから、StringsはJavaで特別な扱いをしています。そして、何かがキャッシュされているかどうかは、おそらく(ORM、jdbcドライバなどの)実装に依存するでしょうが、それはいくつかの疑いがありますが、すべてのことが正しいとは思わないでしょう。 – Luke