Java における一般的なメモリ リーク シナリオには、外部オブジェクトへの参照の保持、静的参照、無効なリスナー、スレッドローカル変数、循環参照が含まれます。アプリケーション サーバーでの一般的なメモリ リーク シナリオには、サーブレット オブジェクトへの参照を保持するスレッド、永続接続への参照を保持する静的ホルダー、およびコンポーネントから削除されないリスナーが含まれます。
Java における一般的なメモリ リークのシナリオ
メモリ リークはソフトウェア開発における重大な欠陥であり、時間の経過とともに発生する可能性があります。アプリケーションのクラッシュやパフォーマンスの低下につながります。 Java での最も一般的なメモリ リークのシナリオは次のとおりです。
1. 外部オブジェクトへの参照の保持
オブジェクトが外部オブジェクトへの参照を保持する場合、 JVM は、使用されていない外部オブジェクトをガベージ コレクションできません。例:
class Outer { private Inner inner; public Outer() { inner = new Inner(); // 持有对 Inner 的引用 } } class Inner { // ... }
2. 静的参照
静的変数は JVM の永続メモリに保存され、ガベージ コレクションされることはありません。静的変数がオブジェクトへの参照を保持している場合、そのオブジェクトはガベージ コレクションできません。例:
public class Example { private static List<Object> objects = new ArrayList<>(); public static void main(String[] args) { objects.add(new Object()); } }
3. 無効なリスナー
リスナーが使用されなくなったが、まだイベント ソースに接続されている場合、メモリ リークが発生します。例:
import javax.swing.*; public class ListenerLeak { private JButton button; public ListenerLeak() { button = new JButton(); button.addActionListener(e -> { // ... }); } // 忘记从按钮中移除监听器 }
4. スレッド ローカル変数
スレッド ローカル変数は、各スレッドのスレッド ローカル ストレージ (TLS) に保存され、アクティブなままになります。スレッドがアクティブである限り、ガベージ コレクションは行われません。完了したスレッドでスレッドローカル変数を使用すると、メモリ リークが発生する可能性があります。例:
public class ThreadLocalLeak { private static ThreadLocal<Object> threadLocal = new ThreadLocal<>(); public static void main(String[] args) { Thread thread = new Thread(() -> { threadLocal.set(new Object()); // 在线程中设置值 }); thread.start(); thread.interrupt(); // 中断线程 // 线程局部存储未得到清理 } }
5. 循環参照
循環参照は、2 つ以上のオブジェクトが相互に参照するときに発生します。これにより、JVM はそれらが使用されていないことを認識できなくなり、メモリ リークが発生します。例:
public class CycleReference { private CycleReference other; public CycleReference() { other = new CycleReference(); other.other = this; // 循环引用 } }
実際のケース
アプリケーション サーバーでのメモリ リーク
アプリケーション サーバーでの典型的なメモリ リークは次のとおりです。シナリオ:
一般的なメモリ リークのシナリオを理解し、適切なコーディング方法を採用して安定性とパフォーマンスを確保することで、Java アプリケーションでのメモリ リークのリスクを軽減できます。
以上がJava でよくあるメモリ リークのシナリオは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。