我有一个使用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是什么?
2条答案
按热度按时间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在哪里使用等等。
zpqajqem2#
在程序中出现字节或字符数组通常是由于代码使用的字符串。通过查看MAT中的内存支配者,您应该能够看到它们是否被字符串对象引用。
在JDK的一般代码中,int数组的使用要少得多,因此您需要找到它们的主要来源。
但是请注意,在这两种情况下,您在代码中直接使用的内容是不相关的;这种使用很可能来自于隐藏的依赖关系,无论是JVM类还是其他缓存机制,都很可能取决于引用对象的位置,因此下一阶段是使用工具来找出这一点。