为啥我的程序在字节数组中保存 1.5Gb 的内存?

Posted

技术标签:

【中文标题】为啥我的程序在字节数组中保存 1.5Gb 的内存?【英文标题】:Why does my program hold 1.5Gb of memory in a Byte array?为什么我的程序在字节数组中保存 1.5Gb 的内存? 【发布时间】:2016-12-12 18:07:12 【问题描述】:

由于最近报告的一些速度缓慢,我一直在分析堆转储。原来有几个 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 问题:

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

【问题讨论】:

你有什么大得离谱的静态字段吗? 没什么特别的。只是通常的字符串常量,很少超过 70 个字符。 【参考方案1】:

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

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

【讨论】:

我刚刚用一些我经常使用的代码更新了帖子,这可能会导致内存泄漏。 @Razoblade 确保所有文件读取器和写入器都已关闭。 'using' 语句有助于确保正确释放资源。如果可以的话,也要避免使用静态方法。 最后一件事@JakePsimos:即使应用程序在已知会自动关闭它们的 JDK 7 中运行,它也是在 JDK 6 中编译的。它们还会自动关闭吗?不过我会接受你的建议,这只是为了一个好的原因:) 谢谢 我们找到了原因。我应该马上更新这个问题。我更新了描述。【参考方案2】:

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

【讨论】:

以上是关于为啥我的程序在字节数组中保存 1.5Gb 的内存?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 tensorflow 模块会占用所有 GPU 内存? [复制]

为啥将许多小字节数组写入文件比写入一个大数组要快?

即使在需要时也不会进行垃圾收集

为啥我的 C# 应用程序中出现内存不足异常?

为啥复制系列图片总显示没有足够的可用空间

为啥 32 位操作系统支持 4 GB RAM?