visualvm配置文件jvm heap found整数数组占用大量内存

xbp102n0  于 2022-11-07  发布在  其他
关注(0)|答案(2)|浏览(228)

我有一个使用OpenJdk的Sping Boot 程序(jdk1.8)运行在服务器端,每天消耗大约2亿或3亿来自Kafka的数据并写入csv文件。启动后不到2个小时,它使用了超过6GB内存,所以我使用jmap histo转储堆,并找到使用2.6GB int[] array和使用1.3GB byte[] array

但是我没有定义int[]在我的项目中没有byte[]。我正在使用spring kafka(org.springframework.kafka,版本2.3.3)使用kafka消息,使用opencsv(com.opencsv,版本4.6)写入csv。
有人知道原因吗?
下面是我的部分代码:

public <T> Boolean parseDataToFile(String filePath, List<T> data) throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
    if (data == null || data.size() <= 0) {
        return false;
    }
    File file = new File(filePath);
    //创建父目录
    boolean mkdirs = file.getParentFile().mkdirs();
    Writer writer = null;
    try {
        writer = new FileWriter(filePath, true);
        StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer).withThrowExceptions(false).withSeparator(',').build();
        beanToCsv.write(data);
        return true;
    } finally {
        if (writer != null) {
                writer.flush();
                writer.close();
        }
    }
}

添加:在示例视图中,大部分(90%以上)都是未使用的(retained size为0),所以可以GCed?但为什么不呢?这些int[] byte[] data是什么?

ru9i0ody

ru9i0ody1#

感谢@AlBlue和@JurajMartinka。我分析了byte[]数组和int[]数组,并找到了部分答案。int[]数组有166921个示例,使用2.6GB内存(57.3%)。它们中的大多数都没有引用:x1c 0d1xKafka使用了其中的一些:

同时, Spring Boot 加载程序:

另一方面,byte[]数组有39400个示例,使用1.3GB内存(28.8%).其中大部分是Kafka的数据:

一些是其他引用的依赖项:x1c4d 1x指令集
活动对象使用的真实的内存并不大。MAT(Eclipse内存分析器工具)显示只占用了43.6M。

然而,还有很多问题需要弄清楚,比如什么时候GC,Netty在哪里使用等等。

zpqajqem

zpqajqem2#

在程序中出现字节或字符数组通常是由于代码使用的字符串。通过查看MAT中的内存支配者,您应该能够看到它们是否被字符串对象引用。
在JDK的一般代码中,int数组的使用要少得多,因此您需要找到它们的主要来源。
但是请注意,在这两种情况下,您在代码中直接使用的内容是不相关的;这种使用很可能来自于隐藏的依赖关系,无论是JVM类还是其他缓存机制,都很可能取决于引用对象的位置,因此下一阶段是使用工具来找出这一点。

相关问题