由于最近报告的一些缓慢,我一直在分析堆转储。结果发现有几个 1.5GB 字节的数组存放在那里,我无法追踪它们的来源。Eclipse 的 MAT 没有向我显示持有如此大块的类。它只是说“<系统类加载器>”。也许我没有找对地方。
是什么导致这两个庞大的字节数组被保留在那里?该应用程序在 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 build 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
编辑:
这两个字节数组实例没有直接在我的代码中定义。但是,我确实在 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));
}
}
更新: 我用谷歌搜索了字节数组的大小,发现问题的根源不是我的代码,而是我们用于共享缓存并最终删除的 JGroups,所以问题就消失了。这是有问题的 JGroups 问题: