質問: パソコンやスマホのスペックは年々向上しており、メモリを意識せずにコーディングしてもなんとかなる状況(決して良くはない)が増えてきています。 反面、組み込み系やWEBアプリ等では、スペックの制限やアクセスの集中等を考慮し、メモリを意識してコーディングする必要があると考えています。 メモリの節約を図る上では、定数をことごとくメソッドに置き換えることも有効な手段のひとつではないかと考えています。 ですが、そういったコーディングをあまり目にしたことがないので、何かデメリットがあるのではないか?とも感じていますが、考えてもわからないので皆様のお知恵をお借りできればと思います。 その上で、僕自身のJVMの理解、解釈についてもお話をさせてください。 まず、JVMはざっくりとスタック領域とヒープ領域(とパーマネント領域)に分かれています。 メソッドが呼び出されるとメソッドの先頭アドレスがスタック領域に格納され、メソッド終了時に結果(返り値)が取り出され自動的に開放されます。 if文やfor文などの基本構文のスコープの中で宣伝された変数も同様であり、変数単位で考えるならばローカル変数がスタック領域に格納されています。 対して、ヒープ領域にはメソッドが終了しても利用されるデータが格納され、ガベージコレクションにより動的に解放されます。 newして生成したインスタンスの本体もそれらのデータのひとつであり、フィールド定数および変数もこのインスタンスの本体に内包されています。 また、ガベージコレクションにより領域が解放される明確なタイミングをコーディングで指示する事はできません。 つまりは、フィールド定数および変数の使用を最小限にすることで、アプリケーションが使用するメモリの節約になり、Full GCを抑制するという副産物もあるのではないと考えています。 定数に注目しているのは、定数は全てメソッドに置き換え可能だと考えているためです。
回答: 考えたことなかったけど、今考えたことを書いてみる。 ・定数はコンパイル時あるいはJITでインライン展開され、宣言したクラスが参照されなくなる(newやstaticメソッドの戻り値は実行時の可能性が高いが)。同様にメソッドも単純ならコンパイル時にあるいはJITでインライン展開され、参照されなくなる。展開前提だと両者の効率は同じになる(かも知れない)。 ・展開されない場合、メソッド呼び出しにはオーバーヘッドがある。 ・展開されても宣言そのものは残る。パーマネント領域内のフィールド分のメモリとメソッド分のメモリを比較すると、メソッドの方が大きい(確実にそうかどうかは知らない)。 ・単純に、コンパイラや各種最適化(コンパイル時、実行時)が頭良すぎな現状では、正直最適な状態になるコードを予測しづらい。 ・何より、メモリ効率は確かに重要だが、大抵は微々たるものであり、思想を曲げて追及すべきものではない。 本当にメモリ効率を追求したいなら高級言語なんて使わない方がいいって話になるし。 ところで >メソッドの先頭アドレスがスタック領域に格納され これは聞いたことがなかった...認識漏れしてるんだろうか。