On Dienstag, 6. Oktober 2009, Todd Lipcon wrote:
> Loaded from database files:
> Nodes: 1722
> Edges: 20602 (excluding 27418 duplicated)
I made similar observations in analyzing a Web-Application running on
Tomcat. In my case, the problem was not only the very long runtime of
the analyzing step, but also its memory consumption. It eats more then
1.6GB of data, finally failing with OOME.
One part of the problem is a poor implementation of a hash function in
class com.enea.jcarder.analyzer.LockEdge
You can try to replace the current implementation with the following:
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime + mSource.getLockId();
result = prime * result + mSourceContextId;
result = prime * result + mTarget.getLockId();
result = prime * result + mTargetContextId;
result = prime * result
+ (int) (mThreadId ^ (mThreadId >>> 32));
return result;
}
Regards,
Henning
I would be glad to include your good work with "gated locks" in the
official releases!
As you found out, the agent in the current JCarder implementation are
not logging events for MONITOR EXIT and therefore the analyzer can not
differentiate between
synchronized(gate) {
synchronized(lock2) {
synchronized(lock3) { }
}
synchronized(lock3) {
synchronized(lock2) { }
}
}
and:
synchronized(gate) {
synchronized(lock2) {
synchronized(lock3) { }
}
}
synchronized(lock3) {
synchronized(lock2) { }
}
This is not a problem for the current algorithm but is needed for
finding gated locks.
As I said, It would be perfect to include your work in the official
JCarder releases, but there are some issues that I would like to
discuss before:
A. The runtime performance of the Agent was decreased a little bit
when also logging MONITOR EXIT, but not as much as I suspected. One
benchmark[*] indicated that a program analyzed with JCarder was slowed
down about 5 times instead of about 4 times as with the latest
official release.
B. The maximum length of a java method is 65536 bytes. If we don't
instrument more than necessarily we minimize the risk of exceeding
that limit.
C. The runtime performance is probably decreased a little due to the
logging of additional MONITOR ENTER events even for monitors already
entered. The latest official release avoid this because I think it is
common with programs like:
public synchronized void foo() {
...
bar();
}
public synchronized void bar() {
...
}
D. The gated locks analysis (during the analysis phase, not during
agent runtime) is using an additional data structure that requires
more memory.
E. Maybe there are some unusual cases where it happens to be a gated
lock in the unit tests or module test setup, but not in the real
application? Then there might be a potential deadlock in the real
application that is not found. Some people might also argue that lock
cycles are a sign of bad design even if there are no potential
deadlocks?
I thinking about:
1. One performance bottleneck of the JCarder agent is the writing of
events and contexts to the database files. If we are going to log
MONITOR EXIT events I see no reason for storing:
* Anything more than lock id and thread id for MONITOR EXIT events.
* lastTakenLockId or lastTakenLockingContextId for MONITOR ENTER
Am I right? This might minimize the impact of issue A and also issue B
because we don't have to add any context string parameters when
instrumenting MONITOR EXIT.
2. Avoid logging MONITOR ENTER for locks that already are held. We
should be able to call Thread.currentThread().holdslock() in both the
callback for MONITOR ENTER and for MONITOR EXIT and only log the event
if that method returns false. For this to work we must instrument the
code to call the beforeMonitorEnter callback BEFORE the lock is taken
and the afterMonitorExit callback AFTER the lock has been released.
This should solve issue C.
3. A parameter for enabling or disabling the gated lock algorithm
during the analyze. I don't think it needs to be configurable for the
runtime agent. This should solve issue E.
4. One way to handle issue D could be to avoid always storing the
extra information needed for the gated analysis in each node/edge and
instead parse the event database file again if, and only if, cycles
are found, and in that second phase only store the information needed
for finding gates for the already found cycles, not for all
nodes/edges.
What are your thoughts about all this?
[*] The benchmark that I've been using when trying to optimize the
runtime performance of the JCarder agent is the 2006-10 release of
DaCapo ( http://dacapobench.org/ ) with it's xalan-based benchmark. If
you have ideas about more suitable benchmarks, please tell!
/Ulrik
On Thu, Oct 8, 2009 at 1:31 PM, DrScott <news...@gmx.de> wrote:
> I implemented a filter for "monitors of interesst" which solved that
> runtime/memory problem for me. I will post the changes within the next
> days.
A filter like that sounds interesting, I'm looking forward to your post. :-)
/Ulrik
B. The maximum length of a java method is 65536 bytes. If we don't
instrument more than necessarily we minimize the risk of exceeding
that limit.
C. The runtime performance is probably decreased a little due to the
logging of additional MONITOR ENTER events even for monitors already
entered. The latest official release avoid this because I think it is
common with programs like:
public synchronized void foo() {
...
bar();
}
public synchronized void bar() {
...
}
D. The gated locks analysis (during the analysis phase, not during
agent runtime) is using an additional data structure that requires
more memory.
E. Maybe there are some unusual cases where it happens to be a gated
lock in the unit tests or module test setup, but not in the real
application? Then there might be a potential deadlock in the real
application that is not found. Some people might also argue that lock
cycles are a sign of bad design even if there are no potential
deadlocks?
I thinking about:
1. One performance bottleneck of the JCarder agent is the writing of
events and contexts to the database files. If we are going to log
MONITOR EXIT events I see no reason for storing:
* Anything more than lock id and thread id for MONITOR EXIT events.
* lastTakenLockId or lastTakenLockingContextId for MONITOR ENTER
Am I right? This might minimize the impact of issue A and also issue B
because we don't have to add any context string parameters when
instrumenting MONITOR EXIT.
2. Avoid logging MONITOR ENTER for locks that already are held. We
should be able to call Thread.currentThread().holdslock() in both the
callback for MONITOR ENTER and for MONITOR EXIT and only log the event
if that method returns false. For this to work we must instrument the
code to call the beforeMonitorEnter callback BEFORE the lock is taken
and the afterMonitorExit callback AFTER the lock has been released.
This should solve issue C.
3. A parameter for enabling or disabling the gated lock algorithm
during the analyze. I don't think it needs to be configurable for the
runtime agent. This should solve issue E.
4. One way to handle issue D could be to avoid always storing the
extra information needed for the gated analysis in each node/edge and
instead parse the event database file again if, and only if, cycles
are found, and in that second phase only store the information needed
for finding gates for the already found cycles, not for all
nodes/edges.
What are your thoughts about all this?
On Montag, 12. Oktober 2009, you wrote:
> Are you thinking about implementating a filter for "monitors of
> interest" in the instrumentation step, during runtime or in the
> analysing step? They are not mutually exclusive but I think there are
> pros and cons with all the three alternatives.
My implementation works during runtime, so there are no differences in
the instrumentation. This is also due to the fact of absolute absence
of any knowledge in this area... ;-)
For 'unwanted' monitors i just return as far as possible
from 'beforeMonitorEnter'.
I am currently on holiday for about a week. I will post my changes if i
find the time for some 'clean up'. So it may happen not before the end
of my vacation... ;-)
Regards,
Henning
The memory problem i stumbled upon is, that im my case there are many
(!) duplicate cycles, which are reduced not before all cycles have been
collected. A quick test which checks for 'AlikeCycles' also during
cycle detection seems to solve this problem (99% of cycles removed).
But i am not sure if there are situations were it is wrong to do this.
And then there is the impact on execution time, which i did not pay
attention to. Again a candidate for introducing an option?
So i am a little bit afraid of introducing yet another structure in
class Cycle, Todd ;-)
Regards,
Henning
> In order to avoid instrumenting certain classes, make the method
> com.enea.jcarder.agent.instrument.ClassTransformer.instrument return
> null for those classes.
This sounds interesting, but as far as i understand, this filters for
classes/methods where no monitor objects are of interrest at all. My
intention is to filter out some kind of monitor objects, regardless of
where they are used. E.g.:
class A {
public func() {
Object monitor = getMonitor();
synchronized (monitor) {
...
}
ConcreteMonitor cMonitor = ...
synchronized (cMonior) {
...
}
}
}
With your suggested change during the instrumentation it would be
possible to ignore any synchronization within class A resp. A.func()
completely.
What i want to achieve is to filter out only synchronizations on objects
of type "ConcreteMonitor". Do you agree that this is something that
could not be done during instrumentation? In the above code example,
the concrete objects returned by "getMonitor()" can only be checked
during runtime...
I am not sure whether this can be done with instrumentation. I don't
have the neccessary insight of the current implementation, but i think
jCarder's agent is triggered by instrumented code within the class
which uses a monitor and not from the monitor instance itself, right?
Can you help?
Anyway, your suggested filter is also handy.
Regards,
Henning
Finally i found some time to finish my work on jcarder. Please find
attached a patch for the latest version on hg. I'm not sure how the
mailinglist handles attachments, so i send it also directly to you.
The patch includes three changes:
a) filter for class level handling of certain monitors
b) include filter for monitors
c) a better hashcode function for LockEdge
Both filters are configured with a comma separated list
of "expressions". These expressions are simply matched
by "String.startsWith". So the monitor instance of class
com.bla.fasel.Foo
is matched by each of
com.,com.bla.,com.bla.fasel.,com.bla.fasel.Foo
This model has some limitations, but i think it's sufficient in most
cases. The results of the filters ares cached.
Both filter types are defined via a system property:
-Djcarder.classLevel
-Djcarder.include
Example:
-Djcarder.classLevel=com.bla.fasel.Foo,com.foo.
This will handle instances of classes 'com.bla.fasel.Foo'
and 'com.bla.fasel.Fool' as well as all every class below 'com.foo.**'.
a) class level:
Monitors for which their class name matches one of the filter
expressions are not handled individually but on class level. The real
synchronization is still done on the individuals, but not the cycle
detection.
b) include filter:
Only monitors for which their class name matches one of the filter
expressions are analyzed by jCarder.
If the option is missing, every monitor is analyzed.
I am very interessted in the results of your benchmarks.
Best regards,
Henning
Thank you very much Henning for your patch and contribution to
JCarder!
I'm sorry for not answering until now. Your patch is now in the
official hg-repository at http://hg.jcarder.org/jcarder/. I was using
your gmx.de email address as author when creating mercurial change
sets for your patch. I hope that was ok.
I also run two different benchmarks without setting any -D properties.
In one of the benchmarks the performance with your patch was on par
with the latest stable release. In another benchmark it even seemed to
be a little bit faster than the last stable release (still without any
activated filters)! It was a surprise for me. After I added a
synchronization block to the filter code that I believe was missing,
it was on par in both the benchmarks.
Ideally, I would like to see the filter code separated from
EventListener.java, into a separate class but that separation would
probably be easier to achieve if we can purge the enteredMonitors data
structure and instead log MONITOR EXIT events, like Todd suggested.
But there are both pros and cons with such a change and I have not
made up my mind yet.
On Mon, Nov 2, 2009 at 11:02 AM, Ulrik Svensson <ulr...@gmail.com> wrote:
Thank you very much Henning for your patch and contribution to
JCarder!
I'm sorry for not answering until now. Your patch is now in the
official hg-repository at http://hg.jcarder.org/jcarder/. I was using
your gmx.de email address as author when creating mercurial change
sets for your patch. I hope that was ok.
I also run two different benchmarks without setting any -D properties.
In one of the benchmarks the performance with your patch was on par
with the latest stable release. In another benchmark it even seemed to
be a little bit faster than the last stable release (still without any
activated filters)! It was a surprise for me. After I added a
synchronization block to the filter code that I believe was missing,
it was on par in both the benchmarks.
Ideally, I would like to see the filter code separated from
EventListener.java, into a separate class but that separation would
probably be easier to achieve if we can purge the enteredMonitors data
structure and instead log MONITOR EXIT events, like Todd suggested.
But there are both pros and cons with such a change and I have not
made up my mind yet.
I spent a few hours last week trying to get the MONITOR_EXIT logging up to speed. No matter what tricks I tried to pull, I couldn't get it to be as fast as the current release. I'm still of the opinion that I'd rather have the extra features than the speed for my use cases, though :)
On Samstag, 14. November 2009, Todd Lipcon wrote:
> Sorry to bump this back into your collective inboxes, but I'm still
> interested to hear what other people think about getting the
> MONITOR_EXIT logging back into trunk.
Well, i am interested in that, too.
> For my use case, jcarder is seomwhat useless without it, since it
> catches so many false positives. Granted, the cyclic lock ordering
> gated by a higher level lock is bad style and a code smell, but I'm
> dealing with a 300Kloc project. I understand there may be an idea
> how to do the same functionality without logging monitor exits, but
> the algorithm wasn't very clear to me.
Sometimes, code is getting too complex. Gating monitors are an
alternative which may reduce this complexity. There are always pros and
cons... ;-)
Are there changes to keep both possibilities (current algorithm, Todd's
algorithm) side by side?
Regards,
Henning
Hi Todd,
Well, i am interested in that, too.
On Samstag, 14. November 2009, Todd Lipcon wrote:
> Sorry to bump this back into your collective inboxes, but I'm still
> interested to hear what other people think about getting the
> MONITOR_EXIT logging back into trunk.
Sometimes, code is getting too complex. Gating monitors are an
> For my use case, jcarder is seomwhat useless without it, since it
> catches so many false positives. Granted, the cyclic lock ordering
> gated by a higher level lock is bad style and a code smell, but I'm
> dealing with a 300Kloc project. I understand there may be an idea
> how to do the same functionality without logging monitor exits, but
> the algorithm wasn't very clear to me.
alternative which may reduce this complexity. There are always pros and
cons... ;-)
Are there changes to keep both possibilities (current algorithm, Todd's
algorithm) side by side?
Regards,
Henning
--
For more options, visit this group at http://groups.google.com/group/jcarder?hl=.
You received this message because you are subscribed to the Google Groups "JCarder" group.
To post to this group, send email to jca...@googlegroups.com.
To unsubscribe from this group, send email to jcarder+u...@googlegroups.com.
Sorry this took so long, but finally got everything into shape:
http://github.com/toddlipcon/jcarder/tree/cloudera
I did manage to merge in the newest tree from hg and resolve those
conflicts. Unit tests still pass, and I tried the dining philosophers
example with success, but haven't used it for a real workload since
then, so it's worth considering "experimental".
If you like, I can also re-run the benchmarks with this newest
version. There was certainly a speed hit since it records locks both
entering and exiting, but for my use case there are way too many false
positives without.
Thanks!
-Todd
> To unsubscribe from this group, send email to jcarder+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/jcarder?hl=en.
>
>
>
Any word on this? Do you need any further work from me? I'd love to
see this contributed upstream.
Thanks
-Todd
Thank you very much for your excellent work Todd and thanks for
contributing your changes including all the test cases!
It was surprisingly convenient to pull your change sets from your git
repository into hg with the Hg-Git Mercurial Plugin. I included all
your change sets except the last commit to allow jcarder options as
arguments, because I would like to keep command line arguments that
might be used by any java aplication being tested, as separate from
options to the jcarder agent as possible, in order to minimize the
risk of interference between them. Therefore I prefer using only java
properties with a jcarder prefix for jcarder options and not ordinary
java command line arguments.
Once again, thank you very much Todd and I'm sorry it took me so long
to get your contribution into the main repository.
/Ulrik
On Jan 27, 11:33 pm, Todd Lipcon <tlip...@gmail.com> wrote:
> Hey guys,
>
> Any word on this? Do you need any further work from me? I'd love to
> see this contributed upstream.
>
> Thanks
> -Todd
>
> On Mon, Dec 28, 2009 at 4:43 PM, Todd Lipcon <tlip...@gmail.com> wrote:
> > Hi Ulrik,
>
> > Sorry this took so long, but finally got everything into shape:
>
> >http://github.com/toddlipcon/jcarder/tree/cloudera
>
> > I did manage to merge in the newest tree from hg and resolve those
> > conflicts. Unit tests still pass, and I tried the dining philosophers
> > example with success, but haven't used it for a real workload since
> > then, so it's worth considering "experimental".
>
> > If you like, I can also re-run the benchmarks with this newest
> > version. There was certainly a speed hit since it records locks both
> > entering and exiting, but for my use case there are way too many false
> > positives without.
>
> > Thanks!
>
> > -Todd
>
Great news, and thanks a lot for your work integrating! I also found
the hg-git mercurial plugin really useful from the git side.
Regarding the last changeset, note that the "command line arguments"
there aren't actually Java command line arguments. Rather, they're the
javaagent arguments. The change allows me to do the following:
JAVA_TOOL_OPTIONS="-javaagent:/path/to/jcarder.jar=outputdir=/foo/jc-@TIME"
ant run-tests
the JAVA_TOOL_OPTIONS environment will get passed through to any
forked jvms underneath ant. This is how I'm able to run jcarder on the
full suite of unit tests for Hadoop, which is my primary use case.
Does the patch make sense given this explanation?
Thanks
-Todd
Any thoughts on this below? I've written up some instructions on the
Hadoop Wiki for using JCarder with Hadoop:
http://wiki.apache.org/hadoop/HowToUseJCarder and unfortunately I have
to point people to my github repository for now rather than the
JCarder repo itself, since this feature is missing.
In other good news, I've been able to identify a bunch of really
tricky bugs in Hadoop using JCarder. So thanks again for this very
useful tool.
-Todd
Ok, I see. You are right, the javaagent arguments make sense. I pushed
your change set to the main repository.
I’m glad JCarder was useful for identifying those tricky bugs in
Hadoop!
/Ulrik
On 17 Feb, 09:06, Todd Lipcon <tlip...@gmail.com> wrote:
> Hi JCarderers!
>
> Any thoughts on this below? I've written up some instructions on the
> Hadoop Wiki for using JCarder with Hadoop:http://wiki.apache.org/hadoop/HowToUseJCarderand unfortunately I have
> to point people to my github repository for now rather than the
> JCarder repo itself, since this feature is missing.
>
> In other good news, I've been able to identify a bunch of really
> tricky bugs in Hadoop using JCarder. So thanks again for this very
> useful tool.
>
> -Todd
>
>
>
> On Tue, Feb 2, 2010 at 12:18 PM, Todd Lipcon <tlip...@gmail.com> wrote:
> > Hey Ulrik,
>
> > Great news, and thanks a lot for your work integrating! I also found
> > the hg-git mercurial plugin really useful from the git side.
>
> > Regarding the last changeset, note that the "command line arguments"
> > there aren't actually Java command line arguments. Rather, they're the
> > javaagent arguments. The change allows me to do the following:
>
> > JAVA_TOOL_OPTIONS="-javaagent:/path/to/jcarder.jar=outputdir=/foo/jc-@TIME"
> > ant run-tests
>
> > the JAVA_TOOL_OPTIONS environment will get passed through to any
> > forked jvms underneath ant. This is how I'm able to run jcarder on the
> > full suite of unit tests for Hadoop, which is my primary use case.
>
> > Does the patch make sense given this explanation?
>
> > Thanks
> > -Todd
>
> >> For more options, visit this group athttp://groups.google.com/group/jcarder?hl=en.- Dölj citerad text -
>
> - Visa citerad text -