From: Kevin McMurtrie on
I've been assisting in load testing some new high performance servers
running Tomcat 6 and Java 1.6.0_20. It appears that the JVM or Linux is
suspending threads for time-slicing in very unfortunate locations. For
example, a thread might suspend in Hashtable.get(Object) after a call to
getProperty(String) on the system properties. It's a synchronized
global so a few hundred threads might pile up until the lock holder
resumes. Odds are that those hundreds of threads won't finish before
another one stops to time slice again. The performance hit has a ton of
hysteresis so the server doesn't recover until it has a lower load than
before the backlog started.

The brute force fix is of course to eliminate calls to shared
synchronized objects. All of the easy stuff has been done. Some
operations aren't well suited to simple CAS. Bottlenecks that are part
of well established Java APIs are time consuming to fix/avoid.

Is there JVM or Linux tuning that will change the behavior of thread
time slicing or preemption? I checked the JDK 6 options page but didn't
find anything that appears to be applicable.
--
I won't see Google Groups replies because I must filter them as spam
From: Lew on
Kevin McMurtrie wrote:
> I've been assisting in load testing some new high performance servers
> running Tomcat 6 and Java 1.6.0_20. It appears that the JVM or Linux is
> suspending threads for time-slicing in very unfortunate locations. For
> example, a thread might suspend in Hashtable.get(Object) after a call to
> getProperty(String) on the system properties. It's a synchronized
> global so a few hundred threads might pile up until the lock holder
> resumes. Odds are that those hundreds of threads won't finish before
> another one stops to time slice again. The performance hit has a ton of
> hysteresis so the server doesn't recover until it has a lower load than
> before the backlog started.
>
> The brute force fix is of course to eliminate calls to shared
> synchronized objects. All of the easy stuff has been done. Some

You call that "brute force" as if it weren't the actual, correct answer.

> operations aren't well suited to simple CAS. Bottlenecks that are part
> of well established Java APIs are time consuming to fix/avoid.

But necessary. Having repeated calls on system properties that require
synchronization is just plain stupid. System properties are the ones that
don't change during a program run, so they should be (and should have been)
written once into an immutable structure at class-load time and read thence
thereafter. End of synchronization woes for that one.

> Is there JVM or Linux tuning that will change the behavior of thread
> time slicing or preemption? I checked the JDK 6 options page but didn't
> find anything that appears to be applicable.

The jmap/jhat dump utilities have some of that, IIRC. Otherwise you break
into the add-on diagnostic tools.

But really it sounds like your code needs refactoring in that it did not
handle concurrency correctly from jump.

--
Lew
From: Tom Anderson on
On Mon, 31 May 2010, Kevin McMurtrie wrote:

> I've been assisting in load testing some new high performance servers
> running Tomcat 6 and Java 1.6.0_20. It appears that the JVM or Linux is
> suspending threads for time-slicing in very unfortunate locations. For
> example, a thread might suspend in Hashtable.get(Object) after a call to
> getProperty(String) on the system properties. It's a synchronized
> global so a few hundred threads might pile up until the lock holder
> resumes. Odds are that those hundreds of threads won't finish before
> another one stops to time slice again. The performance hit has a ton of
> hysteresis so the server doesn't recover until it has a lower load than
> before the backlog started.
>
> The brute force fix is of course to eliminate calls to shared
> synchronized objects.

Well, yeah.

> All of the easy stuff has been done. Some operations aren't well suited
> to simple CAS. Bottlenecks that are part of well established Java APIs
> are time consuming to fix/avoid.

Sadly true.

> Is there JVM or Linux tuning that will change the behavior of thread
> time slicing or preemption? I checked the JDK 6 options page but didn't
> find anything that appears to be applicable.

I'm not aware of anything. Somewhere out there on the web is a complete
list of the -XX options - see if you can find that and have a read through
it.

tom

--
Yulava? Niob Yam!
From: Eric Sosman on
On 6/1/2010 12:21 AM, Kevin McMurtrie wrote:
> I've been assisting in load testing some new high performance servers
> running Tomcat 6 and Java 1.6.0_20. It appears that the JVM or Linux is
> suspending threads for time-slicing in very unfortunate locations. For
> example, a thread might suspend in Hashtable.get(Object) after a call to
> getProperty(String) on the system properties. It's a synchronized
> global so a few hundred threads might pile up until the lock holder
> resumes. Odds are that those hundreds of threads won't finish before
> another one stops to time slice again. The performance hit has a ton of
> hysteresis so the server doesn't recover until it has a lower load than
> before the backlog started.

You've got "a few hundred threads" all calling System.getProperty
over and over again so rapidly that they get in each other's way? Why?
Seems a very odd situation, but ...

Okay: As a first cut, write your own PropertySurrogate class.
Have it slosh all the System properties into a HashMap instead of
System's Hashtable, and change the System.getProperty calls to
PropertySurrogate.getProperty instead. Since HashMap isn't
synchronized, threads calling PropertySurrogate.getProperty won't
block each other.

If this over-and-over reading and re-reading of the System
properties is because you suspect somebody's changing them, you
could have one thread that just keeps iterating over the System
properties, watching for changes. When it sees a change, it would
update the PropertySurrogate HashMap accordingly. This veriant
needs synchronization, but you could use a ReadWriteLock to allow
multiple read-only threads to access the map simultaneously; they'd
be locked out (briefly) only when the monitoring thread was in the
middle of an update.

Still, it seems to me that what you should be looking at is
the reason for all these repetitive getProperty calls. It sounds
like reading the clock every microsecond to see if it's 2014 yet.

--
Eric Sosman
esosman(a)ieee-dot-org.invalid
From: Patricia Shanahan on
Kevin McMurtrie wrote:
> I've been assisting in load testing some new high performance servers
> running Tomcat 6 and Java 1.6.0_20. It appears that the JVM or Linux is
> suspending threads for time-slicing in very unfortunate locations. For
> example, a thread might suspend in Hashtable.get(Object) after a call to
> getProperty(String) on the system properties. It's a synchronized
> global so a few hundred threads might pile up until the lock holder
> resumes. Odds are that those hundreds of threads won't finish before
> another one stops to time slice again. The performance hit has a ton of
> hysteresis so the server doesn't recover until it has a lower load than
> before the backlog started.
>
> The brute force fix is of course to eliminate calls to shared
> synchronized objects. All of the easy stuff has been done. Some
> operations aren't well suited to simple CAS. Bottlenecks that are part
> of well established Java APIs are time consuming to fix/avoid.
>
> Is there JVM or Linux tuning that will change the behavior of thread
> time slicing or preemption? I checked the JDK 6 options page but didn't
> find anything that appears to be applicable.

I can't help with the substantive question, but I can provide a couple
of search terms that may be useful, "priority inversion" and "priority
inheritance".

Patricia