メモリ リーク: メモリ リークとは、プログラムがメモリを申請した後、割り当てられたメモリ領域を解放できないことを意味します。メモリ リークは大きな影響を与えないようですが、蓄積されたメモリ リークの結果、メモリ オーバーフローが発生します。
メモリ不足によるメモリ オーバーフロー: プログラムがメモリを申請するときに、申請者が使用できる十分なメモリがありません。
メモリリークの分類 (発生方法による分類)
- メモリ リークが頻繁に発生します。メモリ リークのあるコードは複数回実行されるため、実行されるたびにメモリ リークが発生します。
- 散発的なメモリ リーク。メモリ リークを引き起こすコードは、特定の状況または操作下でのみ発生します。頻繁と散発は相対的なものです。特定の状況では、たまにしか起こらないことが一般的になる場合があります。したがって、メモリ リークを検出するには、テスト環境とテスト方法が重要です。
- 1 回限りのメモリ リーク。メモリ リークを引き起こすコードは 1 回だけ実行されるか、アルゴリズムの欠陥により、常に 1 つのメモリ ブロックのみがリークされます。たとえば、クラスのコンストラクターでメモリが割り当てられているが、コンストラクターでメモリが解放されていない場合、メモリ リークは 1 回だけ発生します。
- 暗黙的なメモリ リーク。プログラムは実行中に継続的にメモリを割り当てますが、最後までメモリは解放されません。厳密に言えば、プログラムは要求されたすべてのメモリを最終的に解放するため、ここでメモリ リークは発生しません。しかし、数日、数週間、さらには数か月にわたって実行する必要があるサーバー プログラムの場合、メモリの解放が間に合わないと、最終的にシステムのメモリがすべて使い果たされる可能性があります。したがって、このタイプのメモリ リークを暗黙的メモリ リークと呼びます。
メモリオーバーフローの原因と解決策
メモリオーバーフローの原因
1. データベースから一度に大量のデータを取得するなど、メモリにロードされるデータの量が大きすぎます。
2. コレクション クラス内にオブジェクトへの参照があり、使用後にクリアされないため、JVM がリサイクルできなくなります。
3. コード内に無限ループがあるか、ループによって生成される重複オブジェクト エンティティが多すぎます。
4. 使用されているサードパーティ製ソフトウェアのバグ。
5. 起動パラメータメモリの設定値が小さすぎます。
メモリオーバーフローの解決策
最初のステップは、JVM 起動パラメータを変更し、メモリを直接増やすことです。(-Xms パラメーターと -Xmx パラメーターを忘れずに追加してください。)
2 番目のステップは、エラー ログをチェックして、「OutOfMemory」エラーの前に他の例外やエラーがないかどうかを確認することです。
3 番目のステップは、コードを詳しく調べて分析し、メモリ オーバーフローが発生する可能性のある場所を特定することです。
次の点に注目してください。
1. データベースクエリに全データを一度に取得するクエリがあるか確認します。一般に、一度に 100,000 レコードをメモリにフェッチすると、メモリ オーバーフローが発生する可能性があります。この問題は比較的隠されています。オンラインになる前は、データベース内のデータが少なく、問題が発生する可能性は低かったのですが、オンラインになった後は、データベース内のデータが増え、単一のクエリでメモリ オーバーフローが発生する可能性があります。したがって、特に大規模なシステムでは、データベース クエリにはページングを使用するようにしてください。
2. コード内に無限ループや再帰呼び出しがないか確認します。
3. 新しいオブジェクト エンティティを繰り返し生成する大きなループが存在するかどうかを確認します。
4. List や Map などのコレクション オブジェクトが使用後に消去されていないか確認します。List や Map などのコレクション オブジェクトには常にオブジェクトへの参照があるため、これらのオブジェクトは GC によってリサイクルできません。
ステップ 4 : メモリ表示ツールを使用してメモリ使用量を動的に表示する