0% found this document useful (0 votes)
7 views29 pages

Approaches To Synchronization and GC

The document discusses application scalability, focusing on how performance can improve with additional hardware resources and identifying scalability inhibitors such as hardware limitations and application architecture. It emphasizes the importance of thread management, synchronization, and memory management in achieving optimal performance. The authors conclude that the entire software stack influences scalability and that tuning applications for their deployment environment is essential.

Uploaded by

Arun Seetharaman
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views29 pages

Approaches To Synchronization and GC

The document discusses application scalability, focusing on how performance can improve with additional hardware resources and identifying scalability inhibitors such as hardware limitations and application architecture. It emphasizes the importance of thread management, synchronization, and memory management in achieving optimal performance. The authors conclude that the entire software stack influences scalability and that tuning applications for their deployment environment is essential.

Uploaded by

Arun Seetharaman
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Application Scalability

Mark Streich, Salil Pradhan


Senior Software Engineers
Hewlett-Packard Co.
1105163444 1
Does Your Application
Performance Scale?

• Does the performance of your application


increase by adding more [hardware] resources?
Performance

Ideal

Resources
1105163444 2
Scalability Inhibitors

• May be external to your application


or internal
– Hardware (CPU systems, I/O, network)
– Virtual Machine, Middleware, OS, Etc.
– Architecture of your application

1105163444 3
Application Lifetime
Performance

Startup Steady state

Time

1105163444 4
Where Is Your Application
Spending or Wasting Time?

• Executing application code


• Sleeping
• Contending for locks
• Garbage collecting

1105163444 5
Don’t Get Blind-sided!

1105163444 6
Threads

1105163444 7
Threads: The Good News

• Better way to model independent


real objects
• Exploit parallelism and concurrency
• Your applications can scale!

1105163444 8
Threads: The Bad News

• Correctness could be more difficult to


achieve than with single thread of control
• Too many threads increase resource
(memory, CPU) contention and may
decrease performance

1105163444 9
Thread Implementations

• User threads • Kernel threads


• Limited to a single • Can use Multiple
CPU Processors
• Scheduler built into • Scheduled by the
the Java™ virtual Kernel
machine (JVM)
• A Must for good
• Useful for fast single scalability
CPU applications

1105163444 10
Tips: Thread Usage

• Consider using “thread pooling” to avoid


swamping the system with a large number
of threads (i.e., place objects in queue(s),
and allow a smaller number of threads to
retrieve objects from a queue and work
on them)
• Use Thread.sleep() rather than a loop to
insert a time delay

1105163444 11
Synchronization

1105163444 12
To Synchronize or Not

• All non-atomic updates of data shared


between threads must be synchronized,
otherwise a race condition could occur
• Read/write of all object pointers and all
primitive data except long and double
values is guaranteed to be atomic
– Don’t synchronize pure accessor methods
(unless the underlying value is long/double)

1105163444 13
Synchronized Methods

synchronized void foo(int x, int y){ ..


.. ..
.. if_cmp
if (timeToUpdate()) { ..
this.x_ = x; ..
this.y_ = y; ..
} ..
..
}

1105163444 14
Synchronized Blocks

void foo(int x, int y) { ..


.. ..
..
if_cmp ..
if (timeToUpdate()) {
MonitorEnter
synchronized(this) {
this.x_ = x; ..

this.y_ = y; ..
} MonitorExit
} ..
..
}

1105163444 15
Monitors

• Higher level abstraction


– Bytecode and implicit: MonitorEnter, MonitorExit
– API: notify, notifyAll, wait
– VMs typically use lower level mechanisms
to implement

• No direct VM support for multi-reader,


single-writer locks
– Can be simulated using copying

1105163444 16
Tips

• Try to minimize sharing synchronized


objects across multiple threads
• Minimize time spent in synchronized regions
– Avoid allocating new objects while holding a lock
– Avoid performing long system calls while holding a
lock (e.g., while performing I/O)
– JIT compiler can speed up synchronized blocks

• Don’t use busy-wait loops


– They consume unbounded CPU cycles
– Use wait()and notify()/notifyAll()

1105163444 17
Splitting Monitors

• Synchronized objects may have


independent fields
– Split the object into several objects
– Provide separate monitors within the object for
each item
• You do pay the extra cost of allocation and
object space
– Advanced Virtual Machines may help

1105163444 18
Example: Unnecessary
Contention on ‘This’

public class ProcessingQueue {


Queue lowPriority_;
Queue highPriority_;


public synchronized void insertLowPriority(QueueElement q) {


}
public synchronized void insertHighPriority(QueueElement q) {


}
}

1105163444 19
Example: Split Monitor

public class ProcessingQueue {


Queue lowPriority_;
Queue highPriority_;
Object highPQLock = new Object();

public void insertLowPriority(QueueElement q) {
synchronized(this) {


}
}
public void insertHighPriority(QueueElement q) {
synchronized(highPQLock) {


}
}
}

1105163444 20
Internal VM Synchronization
Mechanisms Can Hurt Too!

• JIT Compilers
– May need to lock various structures shared with
the VM

• Heap Lock
– Global object allocation must synchronize access
to the shared heap, and may cause contention

1105163444 21
Memory Management

1105163444 22
Allocation and Collection

• Allocation
– Heap Lock
– Data Locality
– Stack Allocation
– Thread-local

• Automatic Garbage Collection


– Time not spent doing application’s real task
– May stop-the-world
• Concurrent GC may not need to

1105163444 23
Garbage Collection
Frequently Frees up Memory?

• Use generational GC technology


• Could use arenas to pool objects
class PooledObject {
static List pooled = new List(10);
private PooledObject(…){…}
static public synchronized PooledObject newInstance(…) {
if pooled contains an object, remove and return one
else return new PooledObject(…);
}
public synchronized void Reuse(PooledObject p) {
if list can hold another item, add p to pooled
else allow normal GC to deal with it
}
}

1105163444 24
Garbage Collection Does
Not Free up Much Memory

• Increase the heap size


– If there are increased page faults, increase
physical memory

• Heap at address-space limit?


– Need a 64-bit VM?

• 64-bit Virtual Machines


– The Java™ programming language Spec does not
specify the size of object pointers

1105163444 25
Software Stack

• File/Network
• Graphics
– Is the graphics API scalable

• RMI
– May spawn threads behind your back

• Middleware
– Some may invoke Runtime.gc()too often

1105163444 26
Conclusions

• Entire software stack affects scalability


• Engineering for scalability may impose
extra overhead
• Tune your application for the
deployment platform

1105163444 27
References

• Doug Lea “Concurrent Programming in


Java™”. Addison Wesley.
• Scott Norton, Mark Dipasquale “Thread
Time”. Hewlett Packard Professional
Books, Prentice Hall.

1105163444 28
1105163444 29

You might also like