[logback-dev] synchronization style?

Ceki Gulcu ceki at qos.ch
Sat Jul 4 14:01:12 CEST 2009


Joern Huxhorn wrote:
>>
>> Joern,
>>
>>
>> The numbers regarding *wasted* time above do not bring any new
>> information. Assuming there is thread starvation, those starving
>> threads will sit by idly. There is no new information there. It is
>> just stating the obvious.

> Even if there is no starvation that completely prevents access of any 
> other threads, there is still an impact of logging on the execution of 
> multiple threads.


> Threads are waiting longer than necessary in case of unfair locks. And 
> that's my whole point.
> 
> 1ms delay:
> 2959018000 synchronized
> 2078606000 unfair lock
> 27691000 fair lock
> 
> 10ms delay:
> 7592208000 synchronized
> 9756758000 unfair lock
> 12816000 fair lock

With all due respect, as I see things, the figures given by TimeWasted
application attached to LBCLASSIC-140 [1] are essentially meaningless
because TimeWasted measures the time spent (or wasted) waiting to
access a lock. Here is the relevant code code:

public static class WastedTimeSynchronizedRunnable
   implements Runnable {

   public void run() {
     for(;;) {
       ...
       long wasted=System.nanoTime();
       synchronized(lockObject) {
         counter++;
       }
       wasted=System.nanoTime()-wasted;
     }
   }
}


public static class WastedTimeSynchronizedRunnable
   implements Runnable {

   public void run()
     for(;;) {
       ... omitted code
       lock.lock();
       try {
         counter++;
       } finally {
         lock.unlock();
       }
       wasted=System.nanoTime()-wasted;
     }
   }
}

We all agree that when a single thread grabs the CPU while others
threads starve, the other threads get nothing or very little done, but
that is just the definition of thread starvation. Zero surprise = zero
new information.

[1] http://jira.qos.ch/browse/LBCLASSIC-140

> "Wasted time" means that a processor core isn't working. The higher this 
> value is the less optimal an application is scaling on n-core-systems. 
> And this is *only* caused by unfair locking of the logging system.
> I'm honestly baffled that nobody else seems to care.

I estimate that I've already spent over 3 man days on this question. I
would not have spent this time if I did not care. Other participants
also seem quite interested, some of them might even silently agree
with you. :-)

> Beside all that, I have the opinion that logging should happen in the 
> order that an application would like to log.
> 
> Thread A tries to log "A".
> Thread B tries to log "B".
> Thread C tries to log "C".
> Thread A tries to log "A2".
> 
> Should always log A,B,C,A2 and not A,A2,C,B, which can be the case with 
> unfair locking. I'd consider this a bug.

Come on. You can't just ignore the way the JVM handles time-slicing.

> That's not true, the only monitor that needs to be acquired is the one 
> on (or inside) the appender.

A real-world application, contrary to the small test applications such
as TimeWasted, SynchronizedVsFairLock and others, is likely to have
dependencies on resources other than logging, e.g. a data base,
network connection etc. Thus, under "normal" conditions, thread
starvation is much less likely to occur. The thread hogging a
logging-related lock is eventually bound to wait on another resource
in which time the threads waiting to obtain the logging-related lock
will be able to obtain it.

BTW, invoking Thread.yield() is another way to force a thread to let
other threads run. All I am saying is that a "normal" application will
have these Thread.yield() points naturally and transparently on its
execution path.

>>>> As a side note, and if my memory serves me well, you gather caller
>>>> data for every log call which can have significant impact on
>>>> performance. Are you collecting caller data?
>>
>>> Yes, I do, but performance was absolutely sufficient on a single-core
>>> system - which is quite ironic. Let's just forget about my appender for
>>> the moment. The behavior is similar but less dramatic in case of
>>> FileAppender.
>>
>> Interesting. Could you post your config file? When you say less 
>> dramatic, do you mean the behavior of your application in production? 
>> I guess it could be infeasible to try running your application with 
>> IBM's JDK on your 4-core Solaris machine.
> 
> I have the exact same issue with the Apple implementation of Java which, 
> sadly, isn't a real Sun JVM. I can't post the config right now but it's 
> seriously unspectacular. Nothing special in there.

What is unspectacular? The way the JVM distributes the lock among
competing threads?

>> Collecting caller data might just cause waiting threads to be parked
>> at the kernel instead of spun.
> 
> Regardless of the cause, either collecting the caller data or not, such 
> a behavior simply mustn't happen in my books.

I am trying to solve this issue the best I can. Insisting on fair
locks without exploring alternatives will not get us very far.

Given that collecting caller data is pretty expensive, it might
influence the way the JVM treats threads waiting for a lock (spinning
vs parking) which mat be the cause behind the starvation effects you
are seeing.

Could you please try to set up logging without CallerData in your
application and see what happens?

While I agree with you that the logging framework should not have
undesired side-effects such as thread starvation, a java logging
framework is bound by the limitations of the JVM under which it is
executing. It's *not* logback's responsibility to fix the host JVM.

Also note that Sun excepted my bug report on this issue. See
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6855216

Your request for fair locking in appenders is not
unreasonable. However, it will cause a measurable slow down in a large
number of cases. It also feels like fixing the JVM. So, I need more
evidence before going down the path of fair locking.

Best regards,

> Regards,
> Joern.

-- 
Ceki Gülcü
Logback: The reliable, generic, fast and flexible logging framework for Java.
http://logback.qos.ch


More information about the logback-dev mailing list