Androidでのガベージコレクションについて話している2人のAndroidエンジニアによるビデオを見ていました。はじめに、彼らは列挙型に対して少し冗談を言います。Romain Guyは次のように述べています。「そこで修正する必要があります。列挙型、割り当てられません。それが要点です。」最初は、列挙型が他の言語でこのように機能するため、Romainが冗談を言っただけです。しかし、この後、Chetは、列挙型が実際に割り当てられないことを認めているようですが、いくつかの「メモリ関連」の処理を実行しています(つまり、スタック上に存在します)。この反応は私を混乱させるものです。
https://youtu.be/Zc4JP8kNGmQ?t=96
私の理解では、Javaの列挙型は基本的にクラスインスタンスの固定コレクションであり、メモリの観点からはオブジェクトのインスタンス化と同じくらい優れた実装と見なされるEnum
Object
ため、ヒープに割り当てられます。
しかし、コンパイラが列挙型について引き出すことができる強力なプロパティのために、列挙型には特別なステータスがあると想像できます。同様に、String
リテラルの共有プールのように、さまざまな最適化があることを私は知っています。
現在、アプリケーションで定数として使用するオブジェクトのリストを修正している状況にあります。したがって、これを列挙型またはクラスインスタンス化の配列として実装できます。読みやすさが問題ではないと仮定すると、前者を実行する方がパフォーマンスが高いでしょうか?
列挙型はオブジェクトです。すべてのオブジェクトと同様に、それらはヒープ上に存在します。
実際、次のような単純な列挙型を逆コンパイルすると、次のようになります。
enum Foo { A, B }
それはこのように見えます(いくつかのものは省略されています):
static {};
Code:
0: new #4 // class Foo
3: dup
4: ldc #7 // String A
6: iconst_0
7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #9 // Field A:LFoo;
13: new #4 // class Foo
16: dup
17: ldc #10 // String B
19: iconst_1
20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
23: putstatic #11 // Field B:LFoo;
26: iconst_2
27: anewarray #4 // class Foo
30: dup
31: iconst_0
32: getstatic #9 // Field A:LFoo;
35: aastore
36: dup
37: iconst_1
38: getstatic #11 // Field B:LFoo;
41: aastore
42: putstatic #1 // Field $VALUES:[LFoo;
45: return
これは基本的に次のようなクラスと同じです。
class Bar {
static final Bar A = new Bar("A");
static final Bar B = new Bar("B");
static final Bar[] $VALUES;
static {
Bar[] array = new Bar[2];
array[0] = A;
array[1] = B;
$VALUES = array;
}
private Bar(String name) {}
}
これは次のように逆コンパイルされます。
static {};
Code:
0: new #2 // class Bar
3: dup
4: ldc #3 // String A
6: invokespecial #4 // Method "<init>":(Ljava/lang/String;)V
9: putstatic #5 // Field A:LBar;
12: new #2 // class Bar
15: dup
16: ldc #6 // String B
18: invokespecial #4 // Method "<init>":(Ljava/lang/String;)V
21: putstatic #7 // Field B:LBar;
24: iconst_2
25: anewarray #2 // class Bar
28: astore_0
29: aload_0
30: iconst_0
31: getstatic #5 // Field A:LBar;
34: aastore
35: aload_0
36: iconst_1
37: getstatic #7 // Field B:LBar;
40: aastore
41: aload_0
42: putstatic #8 // Field $VALUES:[LBar;
45: return
列挙型から得られる他のいくつかの特別なものがあります(反射的に折り目が付けられないことの保証など)。しかし実際には、それらは単なる通常のオブジェクトです。
彼らが作ろうとしているのは、列挙型が2回以上割り当てられないということです(本当にシングルトンが必要な場合は、列挙型を実装するのに適した方法です)。したがって、列挙型クラスをロードするために少額の固定費を支払います。ただし、同じインスタンスを何度も再利用できます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加