最近報告された速度低下のため、ヒープ ダンプを分析しています。そこには 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 の問題は次のとおりです。