0

最近報告された速度低下のため、ヒープ ダンプを分析しています。そこには 1.5GB のバイト配列がいくつかあり、それらがどこから来たのかを追跡することはできません。Eclipse の MAT は、そのような巨大なチャンクを保持しているクラスを表示しません。「<system class loader>」とだけ書かれています。たぶん、私は正しい場所を探していません。

ここに画像の説明を入力

これら 2 つの巨大なバイト配列が保持されている原因は何ですか? アプリは Websphere Application Server で実行されます。アプリを実行している環境に関するJVM情報を次に示します。ありがとう

  • コンパイル: JVM 1.6
  • 環境 Java バージョン : JRE 1.7.0 Linux amd64-64 build 20130421_145945 (pxa6470sr4fp1ifix-20130423_02(SR4 FP1+IV38579+IV38399+IV40208) )
  • 仮想マシンのバージョン: VM ビルド R26_Java726_SR4_FP1_2_20130421_2353_B145945
    Just-In-Time(JIT) コンパイラ スイッチ、Ahead-Of-Time (AOT) コンパイラ スイッチ、コンパイラ バージョン: r11.b03_20130131_32403ifx4
  • ガベージ コレクターのバージョン: GC - R26_Java726_SR4_FP1_2_20130421_2353_B145945_CMPRSS
  • Java ヒープ情報
    • -Xmx (最大 Java ヒープ サイズ) : 4096m
    • -Xms (初期 Java ヒープ サイズ) : 1024m
    • -Xscmx (Java クラス データ共有キャッシュ サイズ) : 90M
    • -Xscmaxaot (AOT データに使用できるキャッシュ内の最大バイト数) : 4M

編集:

これらの 2 バイト配列インスタンスは、私のコードでは直接定義されていません。ただし、給与計算のバルク ファイルを読み書きするために、util クラス内でこれらのメソッドを常に使用しています。一時ファイルと入力ストリームの絶え間ない作成がそれと関係があるのだろうか.

public abstract class IOUtils {
public static Logger log = LoggerFactory.getLogger(IOUtils.class);
private IOUtils() {}
public static String readFirstLine(File f) {
    String line = null;
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader(f));

        line = reader.readLine();
    } catch (IOException e) {
        log.warn("error reading header", e);
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                log.warn("error closing file", e);
            }
        }
    }
    return line;

}


public static File multipartFileToFile(MultipartFile mFile) throws IOException {
    File convFile = File.createTempFile(mFile.getOriginalFilename(), ".tmp");
    convFile.createNewFile(); 
    org.apache.commons.io.IOUtils.copy(mFile.getInputStream(), new FileOutputStream(convFile));
    return convFile;
}

public static File multipartFileToFile(MultipartFile mFile, String suffix) throws IOException, IllegalStateException {
    File tmpFile = File.createTempFile(mFile.getOriginalFilename(), suffix);
    mFile.transferTo(tmpFile);

    return tmpFile;
}


public static byte[] readBytes(File file) throws IOException {
    return org.apache.commons.io.IOUtils.toByteArray(new FileInputStream(file), file.length());
}


public static void writeBytes(File file, byte[] data) throws IOException {
    org.apache.commons.io.IOUtils.write(data, new FileOutputStream(file));
}

}

更新: bytearray のサイズを Google で調べたところ、問題の原因は私のコードではなく、共有キャッシュに使用していた JGroups であることが判明したため、問題は解消されました。問題の JGroups の問題は次のとおりです。

https://issues.jboss.org/browse/JGRP-1117

4

2 に答える 2

1

コードなどの有用な情報を提供していないため、明確な答えを出すことはほとんど不可能です.

Java のガベージ コレクターは、メモリへの参照がない場合、最終的にメモリを解放します。配列を null に設定してみて、何らかの方法で不要なメモリへの参照を維持している関数、クラス、またはスレッドがないことを確認してください。

于 2016-12-12T18:39:59.797 に答える