赞一个,之前也想也写一下我的实践过程,觉得这篇基本把我要写的都写了。
静态扫描不是简单的引入一个工具、部署一下就完事儿的,这也是这个文章的优点,写了一个完整的技术 topic 实践过程。
补充几点:
理论上有可能,但是实际上会有很多问题,就文中的例子,有打出堆栈,代码也是开源的,当时我们很多人定位这个问题,包括熟悉该框架的算法工程师,都没有找到原因。再举个例子,美团技术博客的文章:https://tech.meituan.com/2018/10/18/netty-direct-memory-screening.html ,之前也找了不少资料,个人觉得 Java 的内存泄漏很难做到仅凭堆栈就一目了然,不如你给个例子?
多谢指出问题。
看的很细心,是有点问题,原因是这样,报警的是线上服务机器是 8C 的,当时持续时间较长,而且服务是混部的,为了整体服务稳定,让 op 手动重启服务了,所以没留下现场信息。后面的截图都是线下测试环境重现时候的截图,线下机器配置是 4C,已在正文指出。
当我们说内存泄漏
:https://en.wikipedia.org/wiki/Memory_leak ,其实隐含了是内存不合理的使用行为,相对应的是你提到的程序正常使用(其实两者没有严格的区分,存在一些灰色的地带),这些都是对内存使用行为的描述,但我们关注的是结果,也就是内存不足时引发的频繁 GC,这回导致 CPU 高占用,服务不可用或者延迟突增。所以,是什么原因其实没有不重要,出现这种情况都是需要暴露出来的问题。
然后是技术层面,如何确认造成内存高占用原因的合理性(前面提到的灰色地带),首先需要定位到根本原因,然后要结合实际情况看合理性。举几个例子:如果一个程序,为了高性能,需要大量的内存作为缓存,但是客观实际是机器没有那么多内存,那就不合理,如果内存很多那就很合理。然后看文中指出的例子,对程序基本没有好处,但是内存占用却很大,那合理性就基本没有。
Update:看了你补充的问题,没遇到过类似问题,信息不足,所以给不出什么建议。另外,我定位这个问题之前之前对 Java 也基本没什么了解,相关知识都是定位过程中学习的,也不是什么大佬,同样你也不用小白自居。遇到问题解决问题就行了。
对的,JVM 有很多优化的技术(编译器同理),所以除非对 JVM 实现细节很熟悉。不要自己写 benchmark 代码,而是用 JMH,这个框架会去掉这些优化。
你这么测试一段代码的性能是不科学的(主要是指使用循环放大语句耗时),里面有很多想像不到的坑。正确的思路是使用 JMH 测试,可以参考一下这个文章:https://www.cnkirito.moe/java-jmh/。
@debugtalk 之前给的例子有问题,没有暴漏出 bug,第二次 commit 新增了单元测试,可以暴漏问题,2.0 也试过了一样有问题的。
借楼问一下,给 issue #450 提的 PR 为啥一直不给过呀~