Java提供了两种获取当前时间的方法:System.nanoTime()
和System.currentTimeMillis()
。第一个给出一个纳秒的结果,但实际精度要比那个(很多微秒)差。
JVM是否已为每台特定机器提供最佳价值? 否则,是否有一些Java库可以通过绑定到特定系统来提供更精细的测量?
答案 0 :(得分:15)
获得超精确时间测量的问题在于某些处理器不能/不能提供如此微小的增量。
据我所知,System.currentTimeMillis()
和System.nanoTime()
是您能找到的最佳衡量标准。
请注意,两者都返回long
值。
答案 1 :(得分:5)
在Java测量时间到纳秒级别时,这有点毫无意义;偶尔的GC命中将很容易消除这可能给出的任何准确性。在任何情况下,文档都指出虽然它提供纳秒精度,但它与纳秒精度不同;并且有些操作系统在任何情况下都不报告纳秒(这就是为什么你在访问时会发现量化为1000的答案;这不是运气,而是限制)。
不仅如此,而且取决于操作系统实际实现的功能,您可能会发现无论如何都会出现量化结果(例如总是以64或128而不是中间值结束的答案)。
值得注意的是,该方法的目的是找到一些(附近)开始时间和现在之间的两个时间差;如果你在长时间运行的应用程序的开头采用System.nanoTime(),然后很长一段时间后采用System.nanoTime(),它可能已经远离实时。所以你应该只在不到1秒的时间内使用它;如果你需要比这更长的运行时间,毫秒就足够了。 (如果不是,那么补上最后几个数字;你可能会给客户留下深刻印象,结果也同样有效。)
答案 2 :(得分:1)
不幸的是,我认为java RTS目前还不够成熟。
Java时间确实试图提供最佳价值(他们实际上委托本机代码来调用获取内核时间)。但是,JVM规范使得这种粗略的时间测量免责声明主要用于GC活动和底层系统的支持。
除非你的应用不需要做GC,否则我还没弄清楚如何解决#1问题。一个体面和中等大小的应用程序可能偶尔花费几十毫秒的GC停顿时间。如果你的精度要求低于10毫秒,你可能会运气不好。
至于#2,你可以tune the linux kernal提供更高的精确度。但是,由于现在内核上下文更频繁地切换,所以你的盒子也越来越少了。
也许,我们应该从不同的角度来看待它。有没有理由说OPS需要10ms以下的精度?是否可以告诉Ops精度为10ms并且还查看当时的GC日志,因此他们知道在没有GC活动的情况下,时间是+ 1-10ms准确吗?
答案 3 :(得分:0)
如果您想要记录纳秒级别的某种类型的现象,您真正需要的是real-time operating system。定时器的准确性将在很大程度上取决于操作系统的high resolution timer和底层硬件的实现。
但是,由于可以使用RTOS版本,因此您仍然可以继续使用Java。
答案 4 :(得分:0)
JNI: 创建一个简单的函数来访问ARM中的英特尔RDTSC指令或协处理器p15的PMCCNTR寄存器。
纯Java: 如果你愿意延迟到时钟滴答,你可能会得到更好的价值。您可以旋转检查System.nanoTime()直到值更改。例如,如果您知道System.nanoTime()的值在您的平台上按DELTA更改每10000次循环迭代,则实际事件时间为finalNanoTime-DELTA * ITERATIONS / 10000。在进行实际测量之前,您需要“预热”代码。
Hack(仅用于分析等): 如果垃圾收集让你失望,你总是可以使用在第二个jvm中运行的高优先级线程来测量时间,这不会创建对象。让它在用作时钟的共享内存中旋转增量。