16.1 자바 메모리 모델은 무엇이며, 왜 사용하는가?
적절한 동기화 방법을 사용하지 않았다면 특정 스레드에서 변수에 할당된 최신 값을 읽어가지 못할 수도 있다.
- 변수의 값을 메모리에 저장하는 대신 CPU 의 레지스터에 보관할 수도 있고
- CPU 프로세서는 프로그램을 순차적으로 실행하거나 병렬적으로 실행할 수도 있고
- 사용하는 캐시의 형태에 따라서 할당된 값이 메모리에 보관되는 시점에 차이가 있을 수도 있고
- CPU 내부의 캐시에 보관된 할당 값이 다른 CPU 의 시야에는 보이지 않을 수도 있다.
병렬 프로그램이라 하더라도 대부분의 시간은 스레드 내부에서 각자의 작업을 처리하기 때문에,
스레드 간의 작업 조율 기능에 자원을 많이 낭비하는 일은 이득도 없으면서 성능만 떨어뜨릴 수 있다.
- 스레드 간의 작업을 조율하는 데 꼭 필요한 데이터만을 공유해 사용하는 것이 올바른 방법이고,
JVM 은 동기화 기능을 사용하는 부분에 한해서 프로그램이 스레드 간의 조율을 하고자 한다.
- JMM 은 변수에 저장된 값이 어느 시점부터 다른 스레드의 가시권에 들어가는지에 대해,
JVM 이 해야만 하는 최소한의 보장만 할 뿐이다.
16.1.1 플랫폼 메모리 모델
JMM
프로그램이 메모리 구조에서 어느 정도의 기능을 사용할 수 있을지에 대한 정보를 제공하고, 메모리의 내용을 서로 공유하고자할 때 프로세서 간의 작업을 조율하기 위한 명령어 (메모리 베리어, 펜스) 를 제공한다.
Java synchronized 키워드와 Memory Barrier
JSR-133 Java Memory Model and Thread Specification 1.0 Proposed Final Draft
JSR 133 (Java Memory Model) FAQ 번역
- 캐시 일관성 (cache coherence)
- 메모리를 공유하는 멀티프로세서 시스템은 각자의 프로세서 안에 캐시 메모리를 갖고 있으며, 캐시 메모리의 내용은 주기적으로 메인 메모리와 동기화된다. 하드웨어 프로세서 아키텍처는 저마다 다른 캐시 일관성을 지원한다.
- 단, 멀티프로세서 시스템에서 각 프로세서가 서로 다른 프로세서가 하는 일은 모두 알 수 있도록 하려면 부하를 안고 가야한다. 따라서 프로세서는 대부분 성능을 높이고자 캐시 메모리의 일관성을 약간씩 희생하곤 한다.
- 순차적 일관성 (sequential consistency)
- 프로그램이 실행되는 과정에서 변수에 마지막으로 설정한 값을 어떤 프로세서건 간에 정확하게 읽어낼 수 있다고 가정한다. 하지만 어떤 프로세서도 순차적 일관성을 지원하지 않으며, JMM 도 지원하지 않는다.
- 올바르게 동기화된 프로그램은 순차적 일관성을 갖고 있으며,
프로그램 내부의 작업이 재배치되지 않고 고정된 전역 순서 (global order) 에 따라 실행된다.