为什么我的程序在Byte数组中保存1.5Gb的内存?

时间:2016-12-12 18:07:13

标签: java arrays memory-leaks out-of-memory eclipse-mat

由于最近报道的一些缓慢,我一直在分析堆转储。事实证明,有几个1.5GB的字节数组存在那里,我无法追踪它们的来源。 Eclipse的MAT没有向我展示持有这么大块的类。它只是说“< system class loader>”。也许我不是在寻找合适的地方。

enter image description here

是什么导致这两个大型字节数组被保留在那里?该应用程序在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
    实时(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));
}

}

更新 我用Google搜索了bytearray的大小,发现问题的根源不是我的代码,而是JGroups,我们用它来共享缓存并最终删除,所以问题就消失了。这是有问题的JGroups问题:

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

2 个答案:

答案 0 :(得分:1)

由于您没有提供任何有用的信息,例如代码,因此几乎不可能给出明确的答案。

Java的垃圾收集器最终会在没有引用时释放内存。尝试将数组设置为null,并确保没有任何函数,类或线程以某种方式维护对不需要的内存的引用。

答案 1 :(得分:0)

尝试使用JVisualVM来跟踪堆问题来自哪个类。