我正在研究java进程中突然发生的内存增加。我看到堆的大小一直增长到3-4 GB。通过调查,我发现在一个类中,正在发生日志记录(这是非常频繁的,例如,每1或2毫秒),它在1秒内产生大约4MB的日志。因此,据我所知,这是堆大小增加的原因。而且,在代码从类中出来并停止日志记录之后,堆大小不会减少。这个过程使用log4j-1.2.16.jar。
我有以下问题。
请帮助我理解log4j和jvm的这种行为。我不知道这是否是已知的事情,log4j2已经解决了这个问题。
发布于 2020-12-15 16:29:19
Log4j被标记为生命的终结,所以升级到较新的版本是个好主意。编写大量日志文件可能会导致性能问题,这取决于您如何使用日志API,但您仍然应该能够在不升级的情况下解决一些日志问题。
检查邮件并检查详细信息的级别。一个关键的问题是打印太多的消息或代码,这些消息或代码不会检查日志记录级别,因为即使不需要消息,字符串表达式也会得到评估。这可能是造成内存分配过高和不必要的原因。考虑:
logger.debug("This line causes memory allocations even if not printed: " +value);如果将日志级别更改为WARN,则仍然会执行消息的上述字符串连接,如果value.toString()是一个昂贵的内存操作,那么除了JVM添加的StringBuilder调用之外,还有更多不必要的对象分配。更改log4j调用以在日志记录之前检查级别:
if (logger.isDebugEnabled()) {
logger.debug("The value is: " +value);
}
logger.debug("No need to call logger.isDebugEnabled() for a string literal");使用log4j2,您可以使用格式字符串或Supplier<String>进行日志记录,只有在需要消息时才会评估日志消息的字符串连接。
向System.out写入可能很昂贵,所以请确保控制台中只显示信息消息,并使用一个附录,以便调试消息进入日志文件。
https://stackoverflow.com/questions/65284801
复制相似问题