SlideShare uma empresa Scribd logo
1 de 35
The Java memory
model made easy
How is Java code executed?
Java javac JVM processor
source code byte code machine code
Optimizations are applied almost exclusively after handing responsibility to the
JVM’s runtime where they are difficult to comprehend.
A JVM is allowed to alter the executed program as long as it remains correct.
The Java memory model describes a contract for what a correct program is (in
the context of multi-threaded applications).
The degree of optimization is dependent on the current compilation stage.
foo == 1
Sequential consistency
class Reordering {
int foo = 0;
int bar = 0;
void method() {
foo += 1;
bar += 1;
foo += 2;
}
}
foo == 0
foo == 0
bar == 0
main memory
processor cache
foo == 1
bar == 0bar == 1
bar == 1
foo == 3
foo == 3
void method() {
foo += 1;
bar += 1;
foo += 2;
}
A sequentially inconsistent optimization
void method() {
foo += 1;
foo += 2;
bar += 1;
}
void method() {
foo += 3;
bar += 1;
}
(foo == 0, bar == 0)
(foo == 0, bar == 0)
(foo == 3, bar == 0)
(foo == 3, bar == 1)
optimizationoptimization
(foo == 1, bar == 0)
(foo == 1, bar == 1)
(foo == 3, bar == 1)
(foo == 0, bar == 0)
(foo == 1, bar == 0)
(foo == 3, bar == 0)
(foo == 3, bar == 1)
Scaling performance: cache efficiency does matter
action approximate time (ns)
typical processor instruction 1
fetch from L1 cache 0.5
branch misprediction 5
fetch from L2 cache 7
mutex lock/unlock 25
fetch from main memory 100
2 kB via 1 GB/s 20.000
seek for new disk location 8.000.000
read 1 MB sequentially from disk 20.000.000
Source: https://gist.github.com/jboner/2841832
action approximate time (ns)
typical processor instruction 1
fetch from L1 cache 0.5
branch misprediction 5
fetch from L2 cache 7
mutex lock/unlock 25
fetch from main memory 100
2 kB via 1 GB/s 20.000
seek for new disk location 8.000.000
read 1 MB sequentially from disk 20.000.000
Eventual consistency
class Caching {
boolean flag = true;
int count = 0;
void thread1() {
while (flag) {
count++;
}
}
void thread2() {
flag = false;
}
}
main memory
processor cache
flag == true
count == 0
processor cache
flag == false
count > 0
neverwritestoflagneverwritestocount
1
2
void thread1() {
while (flag) {
count++;
}
}
An eventually inconsistent optimization
void thread1() {
while (true) {
count++;
}
}
optimization
void thread2() {
flag = false;
}
void thread2() {
// flag = false;
}
optimization
Mnemonic: Think of each thread as if it owned its own heap (infinitive caches).
foo/1 = 0x0000
foo/2 = 0xFFFFfoo/2 = 0x0000
Atomicity
class WordTearing {
long foo = 0L;
void thread1() {
foo = 0x0000FFFF;
// = 2147483647
}
void thread2() {
foo = 0xFFFF0000;
// = -2147483648
}
}
main memory (32 bit)
processor cache (32 bit)
1
2
foo/1 = 0xFFFF
foo/2 = 0x0000
foo/2 = 0xFFFF
foo/1 = 0x0000
processor cache (32 bit)
foo/1 = 0xFFFF
ARM PowerPC SPARC TSO x86 AMD64
load-load yes yes no no no
load-store yes yes no no no
store-store yes yes no no no
store-load yes yes yes yes yes
Processor optimization: a question of hardware architecture
ARM
x86
Source: Wikipedia
Mobile devices become increasingly relevant
64%
78% 42%
Americans owning a particular device in 2014.
Source: Pew Research center
What is the Java memory model?
Answers: what values can be observed upon reading from a specific field.
Formally specified by disaggregating a Java program into actions and applying
several orderings to these actions. If one can derive a so-called happens-before
ordering between write actions and a read actions of one field, the Java
memory model guarantees that the read returns a particular value.
class SingleThreaded {
int foo = 0;
void method() {
foo = 1;
assert foo == 1;
}
}
program order
A trivial, single-threaded example:
write action
read action
The JMM guarantees intra-thread consistency resembling sequential consistency.
Java memory model building-blocks
field-scoped method-scoped
final
volatile
synchronized (method/block)
java.util.concurrent.locks.Lock
Using the above keywords, a programmer can indicate that a JVM should
refrain from optimizations that could otherwise cause concurrency issues.
In terms of the Java memory model, the above concepts introduce additional
synchronization actions which introduce additional (partial) orders. Without
such modifiers, reads and writes might not be ordered (weak memory
model) what results in a data race.
A memory model is a trade-off between a language’s simplicity
(consistency/atomicity) and its performance.
volatile boolean ready = false;
Volatile field semantics
class DataRace {
int answer = 0;
void thread1() {
while (!ready);
assert answer == 42;
}
void thread2() {
answer = 42;
ready = true;
}
}
boolean ready = false;
expected execution order
Volatile field semantics: reordering restrictions
while (!ready);
assert answer == 42;
answer = 42;
ready = true;
time
...
...
synchronization order
Important: the synchronized keyword also implies an synchronization order.
Synchronization order is however not exclusive to it (as demonstrated here)!
program order
program order
1. When a thread writes to a volatile variable, all of its previous writes are guarantted
to be visible to another thread when that thread is reading the same value.
2. Both threads must align “their” volatile value with that in main memory.
3. If the volatile value was a long or a double value, word-tearing was forbidden.
happens-before order
This only applies for two threads with a write-read relationship on the same field!
Synchronized block semantics
class DataRace {
boolean ready = false;
int answer = 0;
while (!ready);
assert answer == 42;
}
answer = 42;
ready = true;
}
}
synchronized void thread1() { // might dead-lock!void thread1() {
void thread2() {synchronized void thread2() {
Synchronized block semantics: reordering restrictions
<enter this>
while (!ready);
assert answer == 42;
<exit this>
<enter this>
answer = 42;
ready = true;
<exit this>
time
...
...
synchronization order
program
order
program
order
happens-before order
When a thread releases a monitor, all of its previous writes are guaranteed to be
visible to another thread after that thread is locking the same monitor.
This only applies for two threads with a unlock-lock relationship on the same monitor!
This example assumes that the second thread acquires the monitor lock first.
Thread life-cycle semantics
class ThreadLifeCycle {
int foo = 0;
void method() {
foo = 42;
new Thread() {
@Override
public void run() {
assert foo == 42;
}
}.start();
}
}
foo = 42;
new Thread() {…}.start();
Thread life-cycle semantics: reordering restrictions
<start>;
assert foo == 42;
time
...
...
happens-before order
synchronization order
When a thread starts another thread, the started thread is guaranteed to see all
values that were set by the starting thread.
Similarly, a thread that joins another thread is guaranteed to see all values that
were set by the joined thread.
program
order
program
order
final int foo;
class UnsafePublication {
int foo;
UnsafePublication() {
foo = 42;
}
static UnsafePublication instance;
static void thread1() {
instance = new UnsafePublication();
}
static void thread2() {
if (instance != null) {
assert instance.foo == 42;
}
}
}
class UnsafePublication {
UnsafePublication() {
foo = 42;
}
static UnsafePublication instance;
static void thread1() {
instance = <allocate UnsafePublication>;
instance.<init>();
}
static void thread2() {
if (instance != null) {
assert instance.foo == 42;
}
}
}
Final field semantics
int foo;
instance = <allocate>;
instance.foo = 42;
<freeze instance.foo>
Final field semantics: reordering restrictions
if (instance != null) {
assert instance.foo == 42;
}
time
...
...
happens-before order
dereference order
When a thread creates an instance, the instance’s final fields are frozen. The Java
memory model requires a field’s initial value to be visible in the initialized form to
other threads.
This requirement also holds for properties that are dereferenced via a final field,
even if the field value’s properties are not final themselves (memory-chain order).
constructor
Does not apply for (reflective) changes outside of a constructor / class initializer.
External actions
class Externalization {
int foo = 0;
void method() {
foo = 42;
jni();
}
native void jni(); /* {
assert foo == 42;
} */
}
A JIT-compiler cannot determine the side-effects of a native operation. Therefore,
external actions are guaranteed to not be reordered.
External actions include JNI, socket communication, file system operations or
interaction with the console (non-exclusive list).
program
order
Thread-divergence actions
class ThreadDivergence {
int foo = 42;
void thread1() {
while (true);
foo = 0;
}
void thread2() {
assert foo == 42;
}
}
Thread-divergence actions are guaranteed to not be reordered. This prevents surprising
outcomes of actions that might never be reached.
program
order
In practice: recursive final references
class Tree {
final Leaf leaf;
Tree() {
leaf = new Leaf(this);
}
}
class Leaf() {
final Tree tree;
Leaf(Tree tree) {
this.tree = tree;
}
}
There is nothing wrong with letting a self-reference escape from a constructor.
However, the semantics for a final field are only guaranteed for code that is placed
after an object’s construction. Watch out for outer references of inner classes!
In practice: double-checked locking
class DoubleChecked {
static DoubleChecked getInstance() {
if (instance == null) {
synchronized (this) {
if (instance == null) {
instance = new DoubleChecked();
}
}
return instance;
}
int foo = 0;
DoubleChecked() { foo = 42; }
void method() { assert foo == 42; }
}
It does work! (This is how Scala implements lazy values.)
static DoubleChecked instance;static volatile DoubleChecked instance;
In practice: safe initialization and publication
Source: http://shipilev.net/blog/2014/safe-public-construction/
x86 ARM
1 thread 8 threads 1 thread 4 threads
final wrapper 2.256 2.485 28.228 28.237
enum holder 2.257 2.415 13.523 13.530
double-checked 2.256 2.475 33.510 29.412
synchronized 18.860 302.346 77.560 1291.585
Problem: how to publish an instance of a class that does not define its fields to be final?
measured in ns/op; continuous instance requests
Besides plain synchronization and the double-checked locking idiom, Java offers:
1. Final wrappers: Where double-checked locking requires volatile field access, this
access can be avoided by wrapping the published instance in a class that stores
the singleton in a final field.
2. Enum holder: By storing a singleton as a field of an enumeration, it is guaranteed
to be initialized due to the fact that enumerations guarantee full initialization.
class Atomicity {
volatile int foo = 42;
volatile int bar = 0;
void multiThread() {
while (foo-- > 0) {
bar++;
}
assert foo == 0 && bar == 42;
}
}
class Atomicity {
final AtomicInteger foo = new AtomicInteger(42);
final AtomicInteger bar = new AtomicInteger(0);
void multiThread() {
while (foo.getAndUpdate(x -> Math.max(0, x--)) > 0) {
bar.incrementAndGet();
}
assert foo.get() == 0 && bar.get() == 42;
}
}
In practice: atomic access
// foo = foo - 1
Only single read and write operations are atomic. In contrast, increments or
decrements are not atomic!
// bar = bar + 1
Atomic wrapper types are backed by volatile fields and invoking the class‘s methods
imply the guarantees given by the Java memory model.
In practice: array elements
class DataRace {
volatile boolean[] ready = new boolean[] { false };
int answer = 0;
void thread1() {
while (!ready[0]);
assert answer == 42;
}
void thread2() {
answer = 42;
ready[0] = true;
}
}
Declaring an array to be volatile does not make its elements volatile! In the above
example, there is no write-read edge because the array is only read by any thread.
For such volatile element access, use java.util.concurrent.atomic.AtomicIntegerArray.
Memory ordering in the wild: Spring beans
class SomeBean() {
private Foo foo;
private Bar bar;
void setFoo(Foo foo) {
this.foo = foo;
}
@PostConstruct
void afterConstruction() {
bar = new Bar();
}
void method() {
assert foo != null && bar != null;
}
}
An application context stores beans in a volatile field after their full construction, then
guarantees that beans are only exposed via reading from this field to induce a restriction.
Memory ordering in the wild: Akka actors
class SomeActor extends UntypedActor {
int foo = 0;
@Override
public void onReceive(Object message) {
if (message instanceof Foo) {
foo = 42;
getSelf().tell(new Bar());
} else {
assert foo == 42;
}
}
}
Akka does not guarantee that an actor receives its messages by the same thread.
Instead, Akka stores and receives its actor references by a volatile field on before
and after every message to induce an ordering restriction.
Memory model implementation
synchronized (new Object()) { /* empty */ }
A Java virtual machine typically implements a stricter form of the Java memory
model for pragmatic reasons.
For example, the HotSpot virtual machine issues memory barriers after
synchronization points. These barriers forbid certain types of memory reordering
(load-load, load-store, store-load, store-store).
Relying on such implementation details jeopardizes cross-platform compatibility.
Always code against the specification, not the implementation!
Memory model validation: the academic approach
set of all possible
field values
program
order synchronization
order
happens-before
order commitable
The transitive closure of all orders determines the set of legal outcomes.
Theory deep dive: "Java Memory Model Pragmatics" by Aleksey Shipilёv
Memory model validation: the pragmatic approach
@JCStressTest
@State
class DataRaceTest {
boolean ready = false;
int answer = 0;
@Actor
void thread1(IntResult1 r) {
while (!ready);
r.r1 = answer;
}
@Actor
void thread2() {
answer = 42;
ready = true;
}
}
Important limitations:
1. Not a unit test. The outcome is
non-deterministic.
2. Does not prove correctness, might
discover incorrectness.
3. Result is hardware-dependent.
Other tools:
Concurrency unit-testing frameworks
such as thread-weaver offer the
introduction of an explicit execution
order for concurrent code. This is
achieved by instrumenting a class’s
code to include explicit break points
which cause synchronization. These
tools cannot help with the discovery
of synchronization errors.
A look into the future: JMM9
In the classic Java memory model, order restrictions of volatile fields were only
required for the volatile fields but not for surrounding reads and writes. As a
result, the double-checked locking idiom was for example dysfunctional.
With the JSR-133 which was implemented for Java 5, today’s Java memory
model was published with additional restrictions.
Due to the additional experience with the revised Java memory model and the
evolution of hardware towards 64-bit architectures, another revision of the Java
memory model, the JMM9, is planned for a future version.
1. The volatile keyword is overloaded. It is not possible to enforce atomicity
without enforcing reorder and caching restrictions. As most of today’s
hardware is already 64-bit, the JMM9 wants to give atomicity as a general
guarantee.
2. It is not possible to make a field both final and volatile. It is therefore not
possible to guarantee the visibility of a volatile field after an object’s
construction. The JMM9 wants to give construction shape visibility as a
general guarantee.
Data races
When a read and at least one right are not ordered, a Java program is suffering a
data race. Even in case of a data race, the JMM guarantees certain constraints.
1. Any field returns at least the field type‘s default value. A Java virtual machine
never exposes garbage values to a user.
2. There is no word-tearing in Java. Apart from long and double values, any
field write operation is atomic.
3. The Java memory model forbids circular reasoning (out-of-thin-air values).
http://rafael.codes
@rafaelcodes
http://documents4j.com
https://github.com/documents4j/documents4j
http://bytebuddy.net
https://github.com/raphw/byte-buddy

Mais conteúdo relacionado

Mais procurados

Operating system 23 process synchronization
Operating system 23 process synchronizationOperating system 23 process synchronization
Operating system 23 process synchronizationVaibhav Khanna
 
Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...
Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...
Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...Jérôme Petazzoni
 
A Deep Dive into Kafka Controller
A Deep Dive into Kafka ControllerA Deep Dive into Kafka Controller
A Deep Dive into Kafka Controllerconfluent
 
Memory consistency models and basics
Memory consistency models and basicsMemory consistency models and basics
Memory consistency models and basicsRamdas Mozhikunnath
 
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...Monica Beckwith
 
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all started
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all startedKernel Recipes 2019 - ftrace: Where modifying a running kernel all started
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all startedAnne Nicolas
 
JVM JIT compilation overview by Vladimir Ivanov
JVM JIT compilation overview by Vladimir IvanovJVM JIT compilation overview by Vladimir Ivanov
JVM JIT compilation overview by Vladimir IvanovZeroTurnaround
 
Oracle RAC on Engineered Systems
Oracle RAC on Engineered SystemsOracle RAC on Engineered Systems
Oracle RAC on Engineered SystemsMarkus Michalewicz
 
JVM: A Platform for Multiple Languages
JVM: A Platform for Multiple LanguagesJVM: A Platform for Multiple Languages
JVM: A Platform for Multiple LanguagesKris Mok
 
The ideal and reality of NVDIMM RAS
The ideal and reality of NVDIMM RASThe ideal and reality of NVDIMM RAS
The ideal and reality of NVDIMM RASYasunori Goto
 
Scheduling in Android
Scheduling in AndroidScheduling in Android
Scheduling in AndroidOpersys inc.
 
Oracle Clusterware Node Management and Voting Disks
Oracle Clusterware Node Management and Voting DisksOracle Clusterware Node Management and Voting Disks
Oracle Clusterware Node Management and Voting DisksMarkus Michalewicz
 
High Availability in 37 Easy Steps
High Availability in 37 Easy StepsHigh Availability in 37 Easy Steps
High Availability in 37 Easy StepsTim Serong
 
Demystifying flink memory allocation and tuning - Roshan Naik, Uber
Demystifying flink memory allocation and tuning - Roshan Naik, UberDemystifying flink memory allocation and tuning - Roshan Naik, Uber
Demystifying flink memory allocation and tuning - Roshan Naik, UberFlink Forward
 
How to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineHow to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineChun-Yu Wang
 
Scylla Summit 2022: Scylla 5.0 New Features, Part 1
Scylla Summit 2022: Scylla 5.0 New Features, Part 1Scylla Summit 2022: Scylla 5.0 New Features, Part 1
Scylla Summit 2022: Scylla 5.0 New Features, Part 1ScyllaDB
 
Performance Tuning EC2 Instances
Performance Tuning EC2 InstancesPerformance Tuning EC2 Instances
Performance Tuning EC2 InstancesBrendan Gregg
 
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Mydbops
 
Understanding Android Benchmarks
Understanding Android BenchmarksUnderstanding Android Benchmarks
Understanding Android BenchmarksKoan-Sin Tan
 

Mais procurados (20)

Operating system 23 process synchronization
Operating system 23 process synchronizationOperating system 23 process synchronization
Operating system 23 process synchronization
 
Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...
Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...
Cgroups, namespaces, and beyond: what are containers made from? (DockerCon Eu...
 
A Deep Dive into Kafka Controller
A Deep Dive into Kafka ControllerA Deep Dive into Kafka Controller
A Deep Dive into Kafka Controller
 
Memory consistency models and basics
Memory consistency models and basicsMemory consistency models and basics
Memory consistency models and basics
 
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
 
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all started
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all startedKernel Recipes 2019 - ftrace: Where modifying a running kernel all started
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all started
 
JVM JIT compilation overview by Vladimir Ivanov
JVM JIT compilation overview by Vladimir IvanovJVM JIT compilation overview by Vladimir Ivanov
JVM JIT compilation overview by Vladimir Ivanov
 
Oracle RAC on Engineered Systems
Oracle RAC on Engineered SystemsOracle RAC on Engineered Systems
Oracle RAC on Engineered Systems
 
JVM: A Platform for Multiple Languages
JVM: A Platform for Multiple LanguagesJVM: A Platform for Multiple Languages
JVM: A Platform for Multiple Languages
 
The ideal and reality of NVDIMM RAS
The ideal and reality of NVDIMM RASThe ideal and reality of NVDIMM RAS
The ideal and reality of NVDIMM RAS
 
Scheduling in Android
Scheduling in AndroidScheduling in Android
Scheduling in Android
 
Oracle Clusterware Node Management and Voting Disks
Oracle Clusterware Node Management and Voting DisksOracle Clusterware Node Management and Voting Disks
Oracle Clusterware Node Management and Voting Disks
 
High Availability in 37 Easy Steps
High Availability in 37 Easy StepsHigh Availability in 37 Easy Steps
High Availability in 37 Easy Steps
 
Inside the jvm
Inside the jvmInside the jvm
Inside the jvm
 
Demystifying flink memory allocation and tuning - Roshan Naik, Uber
Demystifying flink memory allocation and tuning - Roshan Naik, UberDemystifying flink memory allocation and tuning - Roshan Naik, Uber
Demystifying flink memory allocation and tuning - Roshan Naik, Uber
 
How to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineHow to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machine
 
Scylla Summit 2022: Scylla 5.0 New Features, Part 1
Scylla Summit 2022: Scylla 5.0 New Features, Part 1Scylla Summit 2022: Scylla 5.0 New Features, Part 1
Scylla Summit 2022: Scylla 5.0 New Features, Part 1
 
Performance Tuning EC2 Instances
Performance Tuning EC2 InstancesPerformance Tuning EC2 Instances
Performance Tuning EC2 Instances
 
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
 
Understanding Android Benchmarks
Understanding Android BenchmarksUnderstanding Android Benchmarks
Understanding Android Benchmarks
 

Destaque

Java memory presentation
Java memory presentationJava memory presentation
Java memory presentationYury Bubnov
 
Java Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and TuningJava Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and TuningCarol McDonald
 
The Brain Matter of Us
The Brain Matter of UsThe Brain Matter of Us
The Brain Matter of UsMike Huang
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languagesRafael Winterhalter
 
sizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may mattersizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may matterDawid Weiss
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Charles Nutter
 
Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14
Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14
Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14Jayesh Thakrar
 
JAX London 2015: Java vs Nodejs
JAX London 2015: Java vs NodejsJAX London 2015: Java vs Nodejs
JAX London 2015: Java vs NodejsChris Bailey
 
Referring physicians presentation short
Referring physicians presentation shortReferring physicians presentation short
Referring physicians presentation shortAnthony DeSalvo
 
Java gc
Java gcJava gc
Java gcNiit
 
Java GC - Pause tuning
Java GC - Pause tuningJava GC - Pause tuning
Java GC - Pause tuningekino
 
OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"
OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"
OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"Daniel Bryant
 
JavaOne 2016 "Java, Microservices, Cloud and Containers"
JavaOne 2016 "Java, Microservices, Cloud and Containers"JavaOne 2016 "Java, Microservices, Cloud and Containers"
JavaOne 2016 "Java, Microservices, Cloud and Containers"Daniel Bryant
 
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»Anna Shymchenko
 

Destaque (20)

The Java Memory Model
The Java Memory ModelThe Java Memory Model
The Java Memory Model
 
Java Memory Model
Java Memory ModelJava Memory Model
Java Memory Model
 
Java memory presentation
Java memory presentationJava memory presentation
Java memory presentation
 
Java Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and TuningJava Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and Tuning
 
The Brain Matter of Us
The Brain Matter of UsThe Brain Matter of Us
The Brain Matter of Us
 
Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
 
An Overview of Project Jigsaw
An Overview of Project JigsawAn Overview of Project Jigsaw
An Overview of Project Jigsaw
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
sizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may mattersizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may matter
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
 
Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14
Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14
Chicago-Java-User-Group-Meetup-Some-Garbage-Talk-2015-01-14
 
JAX London 2015: Java vs Nodejs
JAX London 2015: Java vs NodejsJAX London 2015: Java vs Nodejs
JAX London 2015: Java vs Nodejs
 
Referring physicians presentation short
Referring physicians presentation shortReferring physicians presentation short
Referring physicians presentation short
 
[BGOUG] Java GC - Friend or Foe
[BGOUG] Java GC - Friend or Foe[BGOUG] Java GC - Friend or Foe
[BGOUG] Java GC - Friend or Foe
 
Java gc
Java gcJava gc
Java gc
 
Java GC - Pause tuning
Java GC - Pause tuningJava GC - Pause tuning
Java GC - Pause tuning
 
OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"
OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"
OSCON EU 2016 "Seven (More) Deadly Sins of Microservices"
 
JavaOne 2016 "Java, Microservices, Cloud and Containers"
JavaOne 2016 "Java, Microservices, Cloud and Containers"JavaOne 2016 "Java, Microservices, Cloud and Containers"
JavaOne 2016 "Java, Microservices, Cloud and Containers"
 
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
 
Java Memory Model
Java Memory ModelJava Memory Model
Java Memory Model
 

Semelhante a The Java memory model made easy

Semelhante a The Java memory model made easy (20)

Java Tutorial | My Heart
Java Tutorial | My HeartJava Tutorial | My Heart
Java Tutorial | My Heart
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini india
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini india
 
Java Tutorial
Java TutorialJava Tutorial
Java Tutorial
 
Java tut1
Java tut1Java tut1
Java tut1
 
Java tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo CahersiveenJava tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo Cahersiveen
 
Javatut1
Javatut1 Javatut1
Javatut1
 
Java tut1
Java tut1Java tut1
Java tut1
 
Synapseindia reviews.odp.
Synapseindia reviews.odp.Synapseindia reviews.odp.
Synapseindia reviews.odp.
 
An introduction to JVM performance
An introduction to JVM performanceAn introduction to JVM performance
An introduction to JVM performance
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
Java tutorials
Java tutorialsJava tutorials
Java tutorials
 
Memory model
Memory modelMemory model
Memory model
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practice
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Medical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsMedical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUs
 
Java coding pitfalls
Java coding pitfallsJava coding pitfalls
Java coding pitfalls
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Java tut1
Java tut1Java tut1
Java tut1
 

Mais de Rafael Winterhalter

Java and OpenJDK: disecting the ecosystem
Java and OpenJDK: disecting the ecosystemJava and OpenJDK: disecting the ecosystem
Java and OpenJDK: disecting the ecosystemRafael Winterhalter
 
The definitive guide to java agents
The definitive guide to java agentsThe definitive guide to java agents
The definitive guide to java agentsRafael Winterhalter
 
Event-Sourcing Microservices on the JVM
Event-Sourcing Microservices on the JVMEvent-Sourcing Microservices on the JVM
Event-Sourcing Microservices on the JVMRafael Winterhalter
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modulesRafael Winterhalter
 
Monitoring distributed (micro-)services
Monitoring distributed (micro-)servicesMonitoring distributed (micro-)services
Monitoring distributed (micro-)servicesRafael Winterhalter
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMRafael Winterhalter
 
Understanding Java byte code and the class file format
Understanding Java byte code and the class file formatUnderstanding Java byte code and the class file format
Understanding Java byte code and the class file formatRafael Winterhalter
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 

Mais de Rafael Winterhalter (12)

Java and OpenJDK: disecting the ecosystem
Java and OpenJDK: disecting the ecosystemJava and OpenJDK: disecting the ecosystem
Java and OpenJDK: disecting the ecosystem
 
The definitive guide to java agents
The definitive guide to java agentsThe definitive guide to java agents
The definitive guide to java agents
 
Byte code field report
Byte code field reportByte code field report
Byte code field report
 
Event-Sourcing Microservices on the JVM
Event-Sourcing Microservices on the JVMEvent-Sourcing Microservices on the JVM
Event-Sourcing Microservices on the JVM
 
Java 10, Java 11 and beyond
Java 10, Java 11 and beyondJava 10, Java 11 and beyond
Java 10, Java 11 and beyond
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modules
 
Monitoring distributed (micro-)services
Monitoring distributed (micro-)servicesMonitoring distributed (micro-)services
Monitoring distributed (micro-)services
 
Java byte code in practice
Java byte code in practiceJava byte code in practice
Java byte code in practice
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
 
Unit testing concurrent code
Unit testing concurrent codeUnit testing concurrent code
Unit testing concurrent code
 
Understanding Java byte code and the class file format
Understanding Java byte code and the class file formatUnderstanding Java byte code and the class file format
Understanding Java byte code and the class file format
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 

Último

Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 

Último (20)

Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 

The Java memory model made easy

  • 2. How is Java code executed? Java javac JVM processor source code byte code machine code Optimizations are applied almost exclusively after handing responsibility to the JVM’s runtime where they are difficult to comprehend. A JVM is allowed to alter the executed program as long as it remains correct. The Java memory model describes a contract for what a correct program is (in the context of multi-threaded applications). The degree of optimization is dependent on the current compilation stage.
  • 3. foo == 1 Sequential consistency class Reordering { int foo = 0; int bar = 0; void method() { foo += 1; bar += 1; foo += 2; } } foo == 0 foo == 0 bar == 0 main memory processor cache foo == 1 bar == 0bar == 1 bar == 1 foo == 3 foo == 3
  • 4. void method() { foo += 1; bar += 1; foo += 2; } A sequentially inconsistent optimization void method() { foo += 1; foo += 2; bar += 1; } void method() { foo += 3; bar += 1; } (foo == 0, bar == 0) (foo == 0, bar == 0) (foo == 3, bar == 0) (foo == 3, bar == 1) optimizationoptimization (foo == 1, bar == 0) (foo == 1, bar == 1) (foo == 3, bar == 1) (foo == 0, bar == 0) (foo == 1, bar == 0) (foo == 3, bar == 0) (foo == 3, bar == 1)
  • 5. Scaling performance: cache efficiency does matter action approximate time (ns) typical processor instruction 1 fetch from L1 cache 0.5 branch misprediction 5 fetch from L2 cache 7 mutex lock/unlock 25 fetch from main memory 100 2 kB via 1 GB/s 20.000 seek for new disk location 8.000.000 read 1 MB sequentially from disk 20.000.000 Source: https://gist.github.com/jboner/2841832 action approximate time (ns) typical processor instruction 1 fetch from L1 cache 0.5 branch misprediction 5 fetch from L2 cache 7 mutex lock/unlock 25 fetch from main memory 100 2 kB via 1 GB/s 20.000 seek for new disk location 8.000.000 read 1 MB sequentially from disk 20.000.000
  • 6. Eventual consistency class Caching { boolean flag = true; int count = 0; void thread1() { while (flag) { count++; } } void thread2() { flag = false; } } main memory processor cache flag == true count == 0 processor cache flag == false count > 0 neverwritestoflagneverwritestocount 1 2
  • 7. void thread1() { while (flag) { count++; } } An eventually inconsistent optimization void thread1() { while (true) { count++; } } optimization void thread2() { flag = false; } void thread2() { // flag = false; } optimization Mnemonic: Think of each thread as if it owned its own heap (infinitive caches).
  • 8. foo/1 = 0x0000 foo/2 = 0xFFFFfoo/2 = 0x0000 Atomicity class WordTearing { long foo = 0L; void thread1() { foo = 0x0000FFFF; // = 2147483647 } void thread2() { foo = 0xFFFF0000; // = -2147483648 } } main memory (32 bit) processor cache (32 bit) 1 2 foo/1 = 0xFFFF foo/2 = 0x0000 foo/2 = 0xFFFF foo/1 = 0x0000 processor cache (32 bit) foo/1 = 0xFFFF
  • 9. ARM PowerPC SPARC TSO x86 AMD64 load-load yes yes no no no load-store yes yes no no no store-store yes yes no no no store-load yes yes yes yes yes Processor optimization: a question of hardware architecture ARM x86 Source: Wikipedia
  • 10. Mobile devices become increasingly relevant 64% 78% 42% Americans owning a particular device in 2014. Source: Pew Research center
  • 11. What is the Java memory model? Answers: what values can be observed upon reading from a specific field. Formally specified by disaggregating a Java program into actions and applying several orderings to these actions. If one can derive a so-called happens-before ordering between write actions and a read actions of one field, the Java memory model guarantees that the read returns a particular value. class SingleThreaded { int foo = 0; void method() { foo = 1; assert foo == 1; } } program order A trivial, single-threaded example: write action read action The JMM guarantees intra-thread consistency resembling sequential consistency.
  • 12. Java memory model building-blocks field-scoped method-scoped final volatile synchronized (method/block) java.util.concurrent.locks.Lock Using the above keywords, a programmer can indicate that a JVM should refrain from optimizations that could otherwise cause concurrency issues. In terms of the Java memory model, the above concepts introduce additional synchronization actions which introduce additional (partial) orders. Without such modifiers, reads and writes might not be ordered (weak memory model) what results in a data race. A memory model is a trade-off between a language’s simplicity (consistency/atomicity) and its performance.
  • 13. volatile boolean ready = false; Volatile field semantics class DataRace { int answer = 0; void thread1() { while (!ready); assert answer == 42; } void thread2() { answer = 42; ready = true; } } boolean ready = false; expected execution order
  • 14. Volatile field semantics: reordering restrictions while (!ready); assert answer == 42; answer = 42; ready = true; time ... ... synchronization order Important: the synchronized keyword also implies an synchronization order. Synchronization order is however not exclusive to it (as demonstrated here)! program order program order 1. When a thread writes to a volatile variable, all of its previous writes are guarantted to be visible to another thread when that thread is reading the same value. 2. Both threads must align “their” volatile value with that in main memory. 3. If the volatile value was a long or a double value, word-tearing was forbidden. happens-before order This only applies for two threads with a write-read relationship on the same field!
  • 15. Synchronized block semantics class DataRace { boolean ready = false; int answer = 0; while (!ready); assert answer == 42; } answer = 42; ready = true; } } synchronized void thread1() { // might dead-lock!void thread1() { void thread2() {synchronized void thread2() {
  • 16. Synchronized block semantics: reordering restrictions <enter this> while (!ready); assert answer == 42; <exit this> <enter this> answer = 42; ready = true; <exit this> time ... ... synchronization order program order program order happens-before order When a thread releases a monitor, all of its previous writes are guaranteed to be visible to another thread after that thread is locking the same monitor. This only applies for two threads with a unlock-lock relationship on the same monitor! This example assumes that the second thread acquires the monitor lock first.
  • 17. Thread life-cycle semantics class ThreadLifeCycle { int foo = 0; void method() { foo = 42; new Thread() { @Override public void run() { assert foo == 42; } }.start(); } }
  • 18. foo = 42; new Thread() {…}.start(); Thread life-cycle semantics: reordering restrictions <start>; assert foo == 42; time ... ... happens-before order synchronization order When a thread starts another thread, the started thread is guaranteed to see all values that were set by the starting thread. Similarly, a thread that joins another thread is guaranteed to see all values that were set by the joined thread. program order program order
  • 19. final int foo; class UnsafePublication { int foo; UnsafePublication() { foo = 42; } static UnsafePublication instance; static void thread1() { instance = new UnsafePublication(); } static void thread2() { if (instance != null) { assert instance.foo == 42; } } } class UnsafePublication { UnsafePublication() { foo = 42; } static UnsafePublication instance; static void thread1() { instance = <allocate UnsafePublication>; instance.<init>(); } static void thread2() { if (instance != null) { assert instance.foo == 42; } } } Final field semantics int foo;
  • 20. instance = <allocate>; instance.foo = 42; <freeze instance.foo> Final field semantics: reordering restrictions if (instance != null) { assert instance.foo == 42; } time ... ... happens-before order dereference order When a thread creates an instance, the instance’s final fields are frozen. The Java memory model requires a field’s initial value to be visible in the initialized form to other threads. This requirement also holds for properties that are dereferenced via a final field, even if the field value’s properties are not final themselves (memory-chain order). constructor Does not apply for (reflective) changes outside of a constructor / class initializer.
  • 21. External actions class Externalization { int foo = 0; void method() { foo = 42; jni(); } native void jni(); /* { assert foo == 42; } */ } A JIT-compiler cannot determine the side-effects of a native operation. Therefore, external actions are guaranteed to not be reordered. External actions include JNI, socket communication, file system operations or interaction with the console (non-exclusive list). program order
  • 22. Thread-divergence actions class ThreadDivergence { int foo = 42; void thread1() { while (true); foo = 0; } void thread2() { assert foo == 42; } } Thread-divergence actions are guaranteed to not be reordered. This prevents surprising outcomes of actions that might never be reached. program order
  • 23. In practice: recursive final references class Tree { final Leaf leaf; Tree() { leaf = new Leaf(this); } } class Leaf() { final Tree tree; Leaf(Tree tree) { this.tree = tree; } } There is nothing wrong with letting a self-reference escape from a constructor. However, the semantics for a final field are only guaranteed for code that is placed after an object’s construction. Watch out for outer references of inner classes!
  • 24. In practice: double-checked locking class DoubleChecked { static DoubleChecked getInstance() { if (instance == null) { synchronized (this) { if (instance == null) { instance = new DoubleChecked(); } } return instance; } int foo = 0; DoubleChecked() { foo = 42; } void method() { assert foo == 42; } } It does work! (This is how Scala implements lazy values.) static DoubleChecked instance;static volatile DoubleChecked instance;
  • 25. In practice: safe initialization and publication Source: http://shipilev.net/blog/2014/safe-public-construction/ x86 ARM 1 thread 8 threads 1 thread 4 threads final wrapper 2.256 2.485 28.228 28.237 enum holder 2.257 2.415 13.523 13.530 double-checked 2.256 2.475 33.510 29.412 synchronized 18.860 302.346 77.560 1291.585 Problem: how to publish an instance of a class that does not define its fields to be final? measured in ns/op; continuous instance requests Besides plain synchronization and the double-checked locking idiom, Java offers: 1. Final wrappers: Where double-checked locking requires volatile field access, this access can be avoided by wrapping the published instance in a class that stores the singleton in a final field. 2. Enum holder: By storing a singleton as a field of an enumeration, it is guaranteed to be initialized due to the fact that enumerations guarantee full initialization.
  • 26. class Atomicity { volatile int foo = 42; volatile int bar = 0; void multiThread() { while (foo-- > 0) { bar++; } assert foo == 0 && bar == 42; } } class Atomicity { final AtomicInteger foo = new AtomicInteger(42); final AtomicInteger bar = new AtomicInteger(0); void multiThread() { while (foo.getAndUpdate(x -> Math.max(0, x--)) > 0) { bar.incrementAndGet(); } assert foo.get() == 0 && bar.get() == 42; } } In practice: atomic access // foo = foo - 1 Only single read and write operations are atomic. In contrast, increments or decrements are not atomic! // bar = bar + 1 Atomic wrapper types are backed by volatile fields and invoking the class‘s methods imply the guarantees given by the Java memory model.
  • 27. In practice: array elements class DataRace { volatile boolean[] ready = new boolean[] { false }; int answer = 0; void thread1() { while (!ready[0]); assert answer == 42; } void thread2() { answer = 42; ready[0] = true; } } Declaring an array to be volatile does not make its elements volatile! In the above example, there is no write-read edge because the array is only read by any thread. For such volatile element access, use java.util.concurrent.atomic.AtomicIntegerArray.
  • 28. Memory ordering in the wild: Spring beans class SomeBean() { private Foo foo; private Bar bar; void setFoo(Foo foo) { this.foo = foo; } @PostConstruct void afterConstruction() { bar = new Bar(); } void method() { assert foo != null && bar != null; } } An application context stores beans in a volatile field after their full construction, then guarantees that beans are only exposed via reading from this field to induce a restriction.
  • 29. Memory ordering in the wild: Akka actors class SomeActor extends UntypedActor { int foo = 0; @Override public void onReceive(Object message) { if (message instanceof Foo) { foo = 42; getSelf().tell(new Bar()); } else { assert foo == 42; } } } Akka does not guarantee that an actor receives its messages by the same thread. Instead, Akka stores and receives its actor references by a volatile field on before and after every message to induce an ordering restriction.
  • 30. Memory model implementation synchronized (new Object()) { /* empty */ } A Java virtual machine typically implements a stricter form of the Java memory model for pragmatic reasons. For example, the HotSpot virtual machine issues memory barriers after synchronization points. These barriers forbid certain types of memory reordering (load-load, load-store, store-load, store-store). Relying on such implementation details jeopardizes cross-platform compatibility. Always code against the specification, not the implementation!
  • 31. Memory model validation: the academic approach set of all possible field values program order synchronization order happens-before order commitable The transitive closure of all orders determines the set of legal outcomes. Theory deep dive: "Java Memory Model Pragmatics" by Aleksey Shipilёv
  • 32. Memory model validation: the pragmatic approach @JCStressTest @State class DataRaceTest { boolean ready = false; int answer = 0; @Actor void thread1(IntResult1 r) { while (!ready); r.r1 = answer; } @Actor void thread2() { answer = 42; ready = true; } } Important limitations: 1. Not a unit test. The outcome is non-deterministic. 2. Does not prove correctness, might discover incorrectness. 3. Result is hardware-dependent. Other tools: Concurrency unit-testing frameworks such as thread-weaver offer the introduction of an explicit execution order for concurrent code. This is achieved by instrumenting a class’s code to include explicit break points which cause synchronization. These tools cannot help with the discovery of synchronization errors.
  • 33. A look into the future: JMM9 In the classic Java memory model, order restrictions of volatile fields were only required for the volatile fields but not for surrounding reads and writes. As a result, the double-checked locking idiom was for example dysfunctional. With the JSR-133 which was implemented for Java 5, today’s Java memory model was published with additional restrictions. Due to the additional experience with the revised Java memory model and the evolution of hardware towards 64-bit architectures, another revision of the Java memory model, the JMM9, is planned for a future version. 1. The volatile keyword is overloaded. It is not possible to enforce atomicity without enforcing reorder and caching restrictions. As most of today’s hardware is already 64-bit, the JMM9 wants to give atomicity as a general guarantee. 2. It is not possible to make a field both final and volatile. It is therefore not possible to guarantee the visibility of a volatile field after an object’s construction. The JMM9 wants to give construction shape visibility as a general guarantee.
  • 34. Data races When a read and at least one right are not ordered, a Java program is suffering a data race. Even in case of a data race, the JMM guarantees certain constraints. 1. Any field returns at least the field type‘s default value. A Java virtual machine never exposes garbage values to a user. 2. There is no word-tearing in Java. Apart from long and double values, any field write operation is atomic. 3. The Java memory model forbids circular reasoning (out-of-thin-air values).