はじめに
メモリに対する考えを相談したので学んだことの備忘録。
用語については自分が分かっている部分はそのまま書いている。
逆に使い方が間違っているようであればご指摘いただきたい(そして教えてほしい)。
メモリ使用の意識
クラスロードについて
main実行時(かその前main関数を持っているクラスがjvmに解釈されたとき)に、
関連するクラスを芋づる式にメモリ上にロードする。
(疑問)クラスロードとかインスタンス生成とか…そこまで意識しなくてよい?
(捉え方によっては叩かれそうだが)そこまで意識しなくてよい。
なぜならばJavaという言語は実装者が(そこまで)メモリ管理を意識しなくてよい言語だから。
この辺りはwikipediaに書いてある。
Java#ガベージコレクション - Wikipedia
メモリ管理を意識するのであればJVMの実装の話になってしまう。
(完全に管理したいのならそもそもCとかC++などを使うべき?)
末端のプログラマでもメモリを意識した方がいい点
staticフィールド(static変数)は必要以上に使わない。
staticフィールドの右辺は意識した方がよい。
staticフィールドはクラスロードの際に作成される。
右辺(初期化)に重い処理を入れてしまうとメモリの圧迫の原因になる。
インスタンス変数やstaticイニシャライザ、イニシャライザも同様に気を付けなければいけない。
インスタンス生成(new)はコストがかかることを意識する。
インスタンス生成はヒープを確保して、オブジェクトを生成する行為。
(インスタンス変数、インスタンスメソッド、イニシャライザの実行)
当たり前だが生成の度にコストがかかる。
(書き直し検討中)staticメソッドでいいものはstaticメソッドにする
副作用がないものは生成コストがかからないstaticがの方が良い。
ここで言う副作用とはインスタンスの状態に依存しないで作成できるかどうか。
いわゆるUtilクラスは積極的に使ってよいということが理解できた。
(mainメソッド実行時にクラスロードされているので生成コストがいらない)
※例:以下のような処理はインスタンスを生成するメリットがないのでstaticにする。
public static int plus(int a, int b){
retrun a + b;
}
immutableを意識する
immutable論争があるという話。
immutableとは・・・
immutable(イミュータブル:不変)とmutable(ミュータブル:変更可能)なオブジェクトのこと。
Javaで代表的なのはString
、LocalDateTime
など。
これについて肯定派と否定派が日夜熱い議論を交わしているらしい。
肯定派:
値の更新がされないことを保つことでプログラムが安全になる。
また新規にインスタンスを作成するとしても元のインスタンスは不要になるはずなので適宜コピーGCで解放されるであろうということ。
否定派:
インスタンスの無駄な生成コスト。
(書き直し検討中)メモリリークの危険。
開発者としては、Stringのように同じ値は同じ参照先を見るように実装できたら気持ちいいだろうが、そこまでロジックに落とすと大変なのでimmutableを意識するようにしていれば良いと思う。
今後、どう実装していけばよいか
そこまで深く考えなくても今まで通りメモリリークしないように実装すればよい。
例だと以下のようなことか。
- GCで拾ってもらえるように変数のスコープを意識する。
- 使わなくなった参照が残らないようにする。(あくまで実装上で)
- (不必要に)static変数を使わない
基本的にはJavaを使っている以上、メモリ管理はJavaに任せる。
(おまけ)GCについて
コピーGCとフルGCがある。
GCログを出せる。(vmオプション)
さらに余談
開発しているシステムのGCログを見せてもらった。
ログでは、起動開始時に何回かfullGCが発生していた。
(昔は実行時にメモリ指定していたようだが何らかの理由により今はやめたらしい。テスト環境だったからかもしれない。)
使う最低ラインが分かっているのであればvmオプションの-Xms
を指定してfullGCが起きないようにすればよいと思った。
GCについてはまた勉強したいと思う。
おわりに
2週間くらい悩んでいたが自分の中でJavaのメモリについてはいったん収束した。
ネットの情報を探したり、色々な人に聞いたのだが自分の中でピンと来なかったので納得できるまでに時間がかかってしまった。
忙しい中、丁寧に解説してくれた現場のリーダーに大きく感謝。
記事リンク
@j5c8k6m8 さんがこの記事を読んでポエムを書いてくださったのでリンクを貼らせていただきました。
Qiita - メモリを意識したプログラミング(実装)は必要か
読ませていただきましたが勉強になりました。