java - 年老代垃圾收集未清除
问题描述
我有一个 java spring boot 项目。当执行与多线程(Executor 服务)相关的代码时,内存会被填满。GC 并未清除此内存。阅读 GC 文档后,才知道终身内存没有被清除。通过使用 Java Profiler 监控 JVM,我注意到这个 Tenured Generation 永远不会被清除(直到满,就我而言)。
- 我怎样才能让 gc 清除终身空间?
我们使用 docker image 运行应用程序
解决方案
这里有两个潜在的问题。
垃圾收集器,只能释放不可访问的对象。因此,如果永久对象仍然可以访问,它们将永远不会被释放。这是一个内存泄漏场景。
JVM 可能没有运行旧/终身空间收集,因为它不需要. JVM 通常只会在它认为有必要/经济的时候运行旧的空间收集器。这实际上是一件好事,因为大多数容易(廉价)收集的垃圾通常都在新空间中。
阅读 gc 文档后,才知道终身内存没有被清除。
这可能是对文档的误读。GC 将收集永久空间中的对象。它应该发生在您开始获得 OOME 之前。
如何让 GC 清除永久空间?
您可以调用System.gc()
... 这给 JVM 一个提示,即现在运行 GC 将是一件好事。然而:
- 这只是一个提示。JVM 可能会忽略它。
- 它可能会或可能不会运行旧空间集合。
- 它不会“清除”老一代。它甚至不一定会释放所有无法访问的对象。
- 调用通常是低效
System.gc()
的。JVM 通常对运行 GC 的最有效时间以及运行哪种 GC 有更好的了解。 - 运行 GC可能实际上并不会释放内存供系统的其余部分使用。
简而言之,调用System.gc()
. 在大多数情况下,它什么也做不了。
如果您的真正问题是内存泄漏,它肯定会有所帮助。如果您正在获得 OOME,那将无济于事。
推荐阅读
- amazon-s3 - 如何使用用户上传的文件更新 .RDS 文件并将其存储在 Shiny(服务器)中以备下次使用?
- mongodb - Elasticsearch,MongoDb,Mongoosastic 查询对象数组
- oracle - 我无法在 oracle 11 g 中添加地理类型的列
- tensorflow - 无法使用 get_tensor_by_name 恢复 Dropout
- node.js - API Gateway 随机切换响应从 403 到 404
- laravel - 是否有可能我创建帖子并且还想在 laravel 中创建后重定向到同一个帖子
- rdf - 子类而不是实例的 RDF 属性的域和范围?
- if-statement - 如何在带有条件的 Kibana 中为“发现”工具创建过滤器?
- installation - 微软服务管理自动化
- python - 无法使用现有规则在新列中创建标签