首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用java 11编译后的OFF堆泄漏

用java 11编译后的OFF堆泄漏
EN

Stack Overflow用户
提问于 2020-05-15 12:24:54
回答 2查看 1.8K关注 0票数 10

在将Spring应用程序maven构建升级到Java 11之后,我们看到java进程的内存消耗不断增加。

工作良好:用Java 8构建JDK +在服务器上运行Java 11

有漏洞:用Java 11构建+在服务器上运行Java 11

泄漏在堆转储甚至本机内存跟踪中都是不可见的,直到物理内存+交换空间满了,进程被系统杀死为止,进程一直在增加。究竟是甚麽问题造成了这类问题呢?

EN

回答 2

Stack Overflow用户

发布于 2020-05-20 20:42:08

在Java11中,ForkJoinPool类的行为略有不同。

最后一次使用线程之前的默认运行时间是60秒。在Java 8中,这是无文档化的,但实际上是在2秒内硬编码的。在超大池的情况下,Java 8实现在池创建两秒钟后终止空闲线程。但是Java 9/11版本的类使它们保持几分钟的活力。

比较线程的数量和生存期。由于在启动应用程序或创建ForkJoinPools对象时,可能不再提前终止未使用的线程,因此线程的延长生存期很容易导致内存问题。

有关类似的问题,请参见以下问题:ForkJoinPool性能Java8 vs 11

在Java9中引入了一个新构造函数来配置该值。要获得与Java8编译相同的行为,您必须在编译到Java9之前显式地将keepAliveTime设置为2秒或缩小ForkJoinPool对象的大小。

票数 1
EN

Stack Overflow用户

发布于 2020-05-24 16:14:23

在深入研究Java的编译器代码之后,我发现了一个有趣的变化,它是在Java 9中引入的,我还没有意识到。此更改可能导致不同的行为,具体取决于编译目标:

虽然众所周知,大多数优化都是由JIT编译器而不是javac完成的,但后者仍然进行了一些代码优化。在Java 9之前,这些优化之一是将字符串连接转换为StringBuilder::append链。从Java 9开始,javac使用了对新引入的java.lang.invoke.StringConcatFactory类的invokedynamic调用,而不是转换到StringBuilder:append调用。因此,当您编译到Java 8时,javac将生成优化的字节代码,而当您编译到Java 9时,优化将在运行时委托给上述内置类。

相应的9月280提供了有关此更改的更多详细信息。JEP 280的一个成功标准是字符串连接性能绝不能倒退。但是JDK-8221760已经报告了一个潜在的性能倒退。根据bug条目,编译到Java 8的字符串级联代码在Java 11u上的性能似乎比编译到Java 9或11的相同代码执行得更好。bug条目仍未解决,因此性能可能不是这里唯一的倒退。

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

https://stackoverflow.com/questions/61819165

复制
相关文章

相似问题

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