Now that I think about it if the caching was done in the Configuration object, 
not stored in some global static, then that would seem like an acceptable 
solution.  I can't image that in a dynamic classloader situation that you would 
be sharing the Configuration object such that it would cause a memory.  Or at 
least in that situation you give the option to disable it.

I found an IBM bug related to this, which is obviously for their J9 JVM, but it 
seems to indicate that java 7 introduced this slow down.  
http://www-01.ibm.com/support/docview.wss?uid=swg1IV53758

Darren

> On Jan 16, 2014, at 4:51 PM, Darren Shepherd <[email protected]> 
> wrote:
> 
> Regarding caching, using Class as the key is a problem that most loggers 
> have.  I'm curious to see how Log4j, slf4j, jcl, etc have addressed it.  
> Being that there's no easily available ConcurrentWeakMap, I can see how this 
> could be difficult.   
> 
> Darren
> 
>> On Jan 16, 2014, at 11:03 AM, Lukas Eder <[email protected]> wrote:
>> 
>> Hi Darren,
>> 
>> I had tried once more and in a different Mission Control tab, I could also 
>> see that getAnnotation() is incredibly expensive. Much more than 
>> getMethods() or anything else. I'll investigate this more in-depth soon. 
>> Further head start on a sensible solution is still appreciated, though.
>> 
>> Cheers
>> Lukas
>> 
>> 
>> 2014/1/15 Darren Shepherd <[email protected]>
>>> I've broken the environment where I tested this, so I'll probably get back 
>>> to you tomorrow.  The stack trace is a bit different.  It is on the 
>>> getAnnotation() call not the getMethods() call.  I'm also using jdk1.7.0_45 
>>> just incase that matters.  I'll see if there is some easy way that I can 
>>> reproduce it too.
>>> 
>>> Darren
>>> 
>>> 
>>>> On Wed, Jan 15, 2014 at 10:41 AM, Lukas Eder <[email protected]> wrote:
>>>> Hi Darren,
>>>> Thanks for reporting this. I'll be tracking this issue as #2955
>>>> https://github.com/jOOQ/jOOQ/issues/2955
>>>> 
>>>> Awesome news that Oracle now ships Mission Control with the JDK 7u40+. 
>>>> Just about when I was going to renew my YourKit license :-)
>>>> So let's see if I read this correctly. The only significant contention I 
>>>> get from the jOOQ integration tests originate from the benchmarks for the 
>>>> into() method:
>>>> 
>>>> <image.png>
>>>> 
>>>> (disregard the AbstractLifecycleListener.testMethod()). Does the above 
>>>> stack trace match your experience? Or is this really on the 
>>>> getAnnotation() calls? Could you please provide me with a screenshot from 
>>>> your side? Is there a way to reproduce this issue easily?
>>>> 
>>>> Note, if you're using the generated record classes, you may prefer using 
>>>> this method:
>>>> - 
>>>> http://www.jooq.org/javadoc/3.2.x/org/jooq/Record.html#into(org.jooq.Table)
>>>> 
>>>> Over this one:
>>>> - 
>>>> http://www.jooq.org/javadoc/3.2.x/org/jooq/Record.html#into(java.lang.Class)
>>>> 
>>>> If you want to implement a cache, you may need to resort to implementing 
>>>> your own RecordMapperProvider:
>>>> http://www.jooq.org/doc/3.2/manual/sql-execution/fetching/pojos-with-recordmapper-provider/
>>>> 
>>>> ... and have that RecordMapperProvider manage a Map<Class<?>, 
>>>> DefaultRecordMapper>, which returns a previously initialised 
>>>> DefaultRecordMapper when the same Class key is encountered. The reason 
>>>> this wasn't implemented in jOOQ is because caches that use Class keys need 
>>>> to properly hook into ClassLoader mechanisms in order to invalidate 
>>>> themselves. In those discussions, we didn't come to a satisfactory 
>>>> solution.
>>>> 
>>>> Cheers
>>>> Lukas
>>>> 
>>>> 2014/1/15 Darren S <[email protected]>
>>>>> Hi Lukas,
>>>>> 
>>>>> I was performance testing my application and surprisingly found the JPA 
>>>>> annotation support in jOOQ to be a pretty significant bottleneck.  The 
>>>>> test I'm doing is essentially a significant amount of "get by id" and 
>>>>> "update by id," a couple hundred threads in parallel.  So the SQL is 
>>>>> super simple.  I'm looking for some guidance on what is the best route 
>>>>> forward.  I had once asked about caching the reflection information in 
>>>>> the default mapper and I believe you said there was some option or it 
>>>>> wasn't cached by default.  Regardless, here's the details.
>>>>> 
>>>>> I highly recommend running Java Mission Control to reproduce this.  Its 
>>>>> freely available and packaged by default in the latest Java 7 JDKs.  If 
>>>>> you run it, look in the threads section for "contention."  Basically what 
>>>>> I'm seeing is that in a 60 second sample, over 30s is waiting on a lock 
>>>>> held while the JDK is parsing the annotations.  Because I have a high 
>>>>> degree of concurrency on a small amount of tables (record classes) this 
>>>>> leads to a significant amount of blocking.  Basically, everytime you list 
>>>>> the methods of a class, you actually get a new list with new Method 
>>>>> instances.  So when you call getAnnotation() it seems to actually parse 
>>>>> the class bytes (or something).  Then it caches the result in the Method 
>>>>> obj.  But if you get the method object over and over again, the caching 
>>>>> is defeated.
>>>>> 
>>>>> I disabled JPA by just changing the code and having isJPAenabled() return 
>>>>> false.  That sped up my application by almost 10x.  I can't actually get 
>>>>> rid of the JPA,  I need the annotations.  But I don't need JPA for the 
>>>>> jOOQ mapper specifically.  Specifically, I need jOOQ to generate the JPA 
>>>>> annotations on the objects so that other programs can read the metadata, 
>>>>> but at runtime I'm just using the generated record classes, so the JPA 
>>>>> information is not needed by jOOQ.  So is there some option to turn on 
>>>>> caching or do I need to implemented a custom mapping provider?
>>>>> 
>>>>> Thanks,
>>>>> Darren
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google Groups 
>>>>> "jOOQ User Group" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>>>> email to [email protected].
>>>>> 
>>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>> 
>>>> -- 
>>>> You received this message because you are subscribed to a topic in the 
>>>> Google Groups "jOOQ User Group" group.
>>>> To unsubscribe from this topic, visit 
>>>> https://groups.google.com/d/topic/jooq-user/YpIpRVVsd5A/unsubscribe.
>>>> To unsubscribe from this group and all its topics, send an email to 
>>>> [email protected].
>>>> 
>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "jOOQ User Group" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to [email protected].
>>> For more options, visit https://groups.google.com/groups/opt_out.
>> 
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "jOOQ User Group" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/jooq-user/YpIpRVVsd5A/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to 
>> [email protected].
>> For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups "jOOQ 
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to