Java堆内存持有大字节数组

标签 java spring-boot java-8 heap heap-memory

我们正在将Java 8 Spring Boot 2用于我们的微服务应用程序。在本地运行负载测试会注意到堆正在消耗内存,但从不释放内存。我正在使用G1垃圾收集器运行该应用程序,并且还通过JVisualVM进行了手动GC,但是仍然无法释放分配的内存。

我进行了堆转储并进行了分析,我可以清楚地看到由System Class Loader创建的大字节数组被列为泄漏可疑对象。我看到字节数组实例将我的HTTP请求保存到端点“/test”。但是负载测试已经完成,线程又回到了运行负载测试之前的状态。

不知道为什么系统类加载器加载的字节数组包含所有这些元素,并且无缘无故地占用了所有这些堆。

JVisualVM

Leak Suspects

byte Array

Objects with Outgoing Ref

/test端点是@RestController类中的唯一方法

@RequestMapping(value = "/test", method = RequestMethod.GET)
@CrossOrigin(origins = "*")
public void test() {
    logger.info("Testing1...");
}

以下是与服务器相关的Spring Boot application.properties:
server.port=8090
server.tomcat.max-threads=200
server.tomcat.accept-count=100
server.tomcat.min-spare-threads=20
server.error.whitelabel.enabled=false
server.max-http-header-size=2097152

最佳答案

Tomcat缓存了许多对象以使其运行更快。使用server.max-http-header-size=2097152设置,您使那些缓存的对象之一声明了2 MB的内存并保留了该内存。在这种情况下,它是Http11OutputBuffer,您可以看到here声明(在您的情况下)2 MB的内存。 Http11OutputBufferHttp11Processor使用,您可以看到here

documentation关于processorCache有以下说法:

The protocol handler caches Processor objects to speed up performance. This setting dictates how many of these objects get cached. -1 means unlimited, default is 200. If not using Servlet 3.0 asynchronous processing, a good default is to use the same as the maxThreads setting. If using Servlet 3.0 asynchronous processing, a good default is to use the larger of maxThreads and the maximum number of expected concurrent requests (synchronous and asynchronous).



所以我的建议是将server.max-http-header-size设置为更合理的值,例如8KB(默认值),并在测试表明您确实需要它时慢慢加倍(related:当总 header 大小大于server.max-http-header-size时,Tomcat抛出“400 Bad Request”)。

关于Java堆内存持有大字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58420606/

相关文章:

java - 未指定 hibernate.search.lucene_version : using LUCENE_CURRENT

java - 使用 LongAdder 计算统计计数器的最大值?

java - Spring 测试主线程陷入应用程序的无限循环

java - 坚持使用 java8 lambda 表达式

java - 使用自定义序列化对象序列化 HashMap

java - 下载不同编码的在线文本

java - 从另一个类访问 Activity 中的 UI 元素

java - 如何处理SendFailedException?

java - 在tomcat上的servlet应用程序中保存文件,如何找出应用程序的根目录?

spring-boot - 如何添加对多个 Thymeleaf 模板模式的支持