ホームページ  >  記事  >  Java  >  Java でよくあるメモリ リークのシナリオは何ですか?

Java でよくあるメモリ リークのシナリオは何ですか?

王林
王林オリジナル
2024-04-13 18:39:02434ブラウズ

Java における一般的なメモリ リーク シナリオには、外部オブジェクトへの参照の保持、静的参照、無効なリスナー、スレッドローカル変数、循環参照が含まれます。アプリケーション サーバーでの一般的なメモリ リーク シナリオには、サーブレット オブジェクトへの参照を保持するスレッド、永続接続への参照を保持する静的ホルダー、およびコンポーネントから削除されないリスナーが含まれます。

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;  // 循环引用
    }
}

実際のケース

アプリケーション サーバーでのメモリ リーク

アプリケーション サーバーでの典型的なメモリ リークは次のとおりです。シナリオ:

  1. スレッドは、サーブレットが完了した後もサーブレット オブジェクトへの参照を保持します。
  2. 静的ホルダー (データベース接続プールなど) は、永続的な接続が不要になった場合でも、その接続への参照を維持します。
  3. リスナーがコンポーネントから削除されなかったため、リスナーの参照が保持されました。

一般的なメモリ リークのシナリオを理解し、適切なコーディング方法を採用して安定性とパフォーマンスを確保することで、Java アプリケーションでのメモリ リークのリスクを軽減できます。

以上がJava でよくあるメモリ リークのシナリオは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。