最近查了个关于 System.nanoTime() 的问题,起因是业务里面将 System.nanoTime() 返回的数值作为了业务中的唯一值,最后发现了值相同的数据,询问编写这块代码的同事,同事反馈说当时编写的时候以为 System.nanoTime() 的精度很高,不会出现重复的数据。但是从现象来看,出现了重复的数据。
我们可以用一段简单的代码复现该问题:
1 | public class Test { |
最近查了个关于 System.nanoTime() 的问题,起因是业务里面将 System.nanoTime() 返回的数值作为了业务中的唯一值,最后发现了值相同的数据,询问编写这块代码的同事,同事反馈说当时编写的时候以为 System.nanoTime() 的精度很高,不会出现重复的数据。但是从现象来看,出现了重复的数据。
我们可以用一段简单的代码复现该问题:
1 | public class Test { |
最近写了些关于 Bit 操作的代码,才发现使用左移操作符时,当右侧操作数(需要移动的位数)大于左侧操作数比特个数时,实际移动位数等同于右侧操作数对左侧操作数比特个数求余。可能说的不是很明白,可以用一个简单的示例来说明,比如以下代码:
1 | public class BitShiftTest { |
严格来说,DeleteOnExitHook 导致的内存占用不应该归结为内存泄漏,开发者应该恰当地使用 java.io.File#deleteOnExit 方法,如果持续对不同的文件调用该方法,那么长时间运行的 JVM 实例的内存最终将被填满。为了规避这个问题,建议应用程序自行进行临时文件管理,而不是依赖于 JVM 退出来进行相应的文件清理操作。
如果通过 Google 搜索 java.io.DeleteOnExitHook memory leak,可知有不少开源项目存在该问题,主要受影响的为长时间运行的服务,java.io.DeleteOnExitHook#files 占用的内存往往在数百兆以上而且随着服务的持续运行会持续增长。
如 HIVE-11768 中提到的 .pipeout 文件问题,其解决方案为自行编写了 ShutdownHookManager 类,该类相比 JDK 提供的 DeleteOnExitHook 新增了 cancelDeleteOnExit 方法,且应用自行管理这部分临时文件的生命周期,不再使用后删除文件并调用 cancelDeleteOnExit 方法移除这部分文件名,以解决内存占用问题。本次 commit 可参考:HIVE-11768 : java.io.DeleteOnExitHook leaks memory on long running Hi… · apache/hive@1a81c26 · GitHub。
附上 JDK 8 中 DeleteOnExitHook 的源码:
1 | /** |
jdk/DeleteOnExitHook.java at jdk8-b120 · openjdk/jdk · GitHub
Memory Leak on DeleteOnExitHook - Stack Overflow
JDK-4513817 File.deleteOnExit consumes memory - Java Bug System
SPARK-14261 Memory leak in Spark Thrift Server - ASF JIRA
首先看一段存在 bug 的代码:
1 | @GuardedBy("isolatedEndpointsSetLock") |
SPARK-39357 pmCache memory leak caused by IsolatedClassLoader - ASF JIRA
SPARK-39357 Fix pmCache memory leak caused by IsolatedClassLoader by tianshuang · Pull Request #36741 · apache/spark · GitHub
Effect of ThreadLocals and side-by-side classloading - Stack Overflow
How isolated are static variables? - Software Engineering Stack Exchange