Why
회의 시간에 Ummm님이 currentTimeMillis 보다는 성능상 nanoTime을 쓰는 것이 좋다고 하셔서 찾아보게 되었다.
예전에 이상민님의 자바 성능 개발자가 반드시 알아야 할 자바 성능 튜닝 이야기에 비슷한 내용이 있었던 것 같은데 너무 오래 전에 읽어서 기억이 나지 않는다.
선 검색
검색해보면 Baeldung.com 에는 Measure Elapsed Time in Java 라는 제목으로 글이 있다.
System.currentTimeMillis의 경우는 wall-clock time이라서 시스템의 시간을 바꾼다거나 외부적인 요인에 의해 시간 점프가 발생할 수 있다고 한다.
nanoTime의 경우 system or wall-clock time에 대한 언급이 따로 없다고 한다.
용어
Wall clock: 현실 세계와 시간 단위가 똑간은 시계. 시스템의 시간을 동기화 할 때 시간의 값이 튀는 일이 발생할 수 있다.
Monotonic clock: 시간 값이 단조 증가하는 시계. 시스템의 시간이 1초 뒤로 돌아가더라고 상관없이 증기를 한다.
Robert Love's book LINUX System Programming 2nd Edition, specifically addresses your question at the beginning of Chapter 11, pg 363:
The important aspect of a monotonic time source is NOT the current value, but the guarantee that the time source is strictly linearly increasing, and thus useful for calculating the difference in time between two samplings
JDK and JVM
JDK에서는 다음과 같이 native 메서드로 export가 되어 있다.
public static native long currentTimeMillis();
public static native long nanoTime();
jvm.cpp에는 다음과 같이 래핑이 되어 있다.
OS에 따라 구현하고 있는 시스템 콜이 다르기 때문이다.
os.hpp
구현은 플랫폼 마다 다르게 되어 있다.
윈도우 (os_windows.cpp)
globals.hpp
globalDefinitions.hpp
LINUX (os_linux.cpp)
jlong os::javaTimeMillis() { timeval time; int status = gettimeofday(&time, NULL); assert(status != -1, "linux error"); return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);}
jlong os::javaTimeNanos() { if (Linux::supports_monotonic_clock()) { struct timespec tp; int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp); assert(status == 0, "gettime error"); jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); return result; } else { timeval time; int status = gettimeofday(&time, NULL); assert(status != -1, "linux error"); jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); return 1000 * usecs; }}
os_linux.hpp
class Linux { friend class os; friend class TestReserveMemorySpecial;
public: static inline bool supports_monotonic_clock() { return _clock_gettime != NULL; }
BSD (os_bsd.cpp)
Solaris (os_solaris.cpp)
'Programing > JVM(Java, Kotlin)' 카테고리의 다른 글
[Java] Class 생성 실험 (0) | 2019.04.01 |
---|---|
[Java] switch와 String 그리고 바이트코드 (0) | 2019.03.22 |
[Java] break label 문 (0) | 2019.03.09 |
[Java] Generic in depth (0) | 2019.01.31 |
Spock Framework 프로젝트에 추가하기 (0) | 2018.10.02 |