首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >日志记录太频繁会导致堆大小急剧增加吗?

日志记录太频繁会导致堆大小急剧增加吗?
EN

Stack Overflow用户
提问于 2020-12-14 06:56:20
回答 1查看 1.3K关注 0票数 0

我正在研究java进程中突然发生的内存增加。我看到堆的大小一直增长到3-4 GB。通过调查,我发现在一个类中,正在发生日志记录(这是非常频繁的,例如,每1或2毫秒),它在1秒内产生大约4MB的日志。因此,据我所知,这是堆大小增加的原因。而且,在代码从类中出来并停止日志记录之后,堆大小不会减少。这个过程使用log4j-1.2.16.jar。

我有以下问题。

  1. 由于频繁的日志记录,log4j是否在堆中创建了太多的对象?如果是,是预期的行为还是log4j中的某些限制在log4j2中得到了解决?
  2. 为什么堆大小没有减少?log4j是否保存对堆中对象的引用,因为它们不是由GC收集的?

请帮助我理解log4j和jvm的这种行为。我不知道这是否是已知的事情,log4j2已经解决了这个问题。

EN

回答 1

Stack Overflow用户

发布于 2020-12-15 16:29:19

Log4j被标记为生命的终结,所以升级到较新的版本是个好主意。编写大量日志文件可能会导致性能问题,这取决于您如何使用日志API,但您仍然应该能够在不升级的情况下解决一些日志问题。

检查邮件并检查详细信息的级别。一个关键的问题是打印太多的消息或代码,这些消息或代码不会检查日志记录级别,因为即使不需要消息,字符串表达式也会得到评估。这可能是造成内存分配过高和不必要的原因。考虑:

代码语言:javascript
复制
logger.debug("This line causes memory allocations even if not printed: " +value);

如果将日志级别更改为WARN,则仍然会执行消息的上述字符串连接,如果value.toString()是一个昂贵的内存操作,那么除了JVM添加的StringBuilder调用之外,还有更多不必要的对象分配。更改log4j调用以在日志记录之前检查级别:

代码语言:javascript
复制
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写入可能很昂贵,所以请确保控制台中只显示信息消息,并使用一个附录,以便调试消息进入日志文件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65284801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档