You can subscribe to this list here.
| 2003 |
Jan
|
Feb
(55) |
Mar
(100) |
Apr
(203) |
May
(330) |
Jun
(190) |
Jul
(302) |
Aug
(323) |
Sep
(197) |
Oct
(245) |
Nov
(490) |
Dec
(330) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(194) |
Feb
(400) |
Mar
(416) |
Apr
(415) |
May
(359) |
Jun
(381) |
Jul
(491) |
Aug
(311) |
Sep
(291) |
Oct
(273) |
Nov
(355) |
Dec
(266) |
| 2005 |
Jan
(306) |
Feb
(303) |
Mar
(520) |
Apr
(346) |
May
(255) |
Jun
(221) |
Jul
(171) |
Aug
(247) |
Sep
(147) |
Oct
(125) |
Nov
(165) |
Dec
(65) |
| 2006 |
Jan
(90) |
Feb
(53) |
Mar
(121) |
Apr
(103) |
May
(113) |
Jun
(103) |
Jul
(104) |
Aug
(67) |
Sep
(78) |
Oct
(82) |
Nov
(78) |
Dec
(70) |
| 2007 |
Jan
(77) |
Feb
(76) |
Mar
(63) |
Apr
(30) |
May
(47) |
Jun
(41) |
Jul
(44) |
Aug
(44) |
Sep
(49) |
Oct
(33) |
Nov
(25) |
Dec
(21) |
| 2008 |
Jan
(45) |
Feb
(13) |
Mar
(15) |
Apr
(12) |
May
(9) |
Jun
(33) |
Jul
(30) |
Aug
(7) |
Sep
(20) |
Oct
(17) |
Nov
(20) |
Dec
(10) |
| 2009 |
Jan
(8) |
Feb
(5) |
Mar
(12) |
Apr
(17) |
May
(19) |
Jun
(97) |
Jul
(77) |
Aug
(33) |
Sep
(24) |
Oct
(41) |
Nov
(16) |
Dec
(32) |
| 2010 |
Jan
(24) |
Feb
(14) |
Mar
(50) |
Apr
(71) |
May
(70) |
Jun
(64) |
Jul
(45) |
Aug
(62) |
Sep
(32) |
Oct
(4) |
Nov
(12) |
Dec
(2) |
| 2011 |
Jan
(1) |
Feb
(3) |
Mar
(4) |
Apr
(3) |
May
(6) |
Jun
(1) |
Jul
(4) |
Aug
(3) |
Sep
(4) |
Oct
(6) |
Nov
(3) |
Dec
(3) |
| 2012 |
Jan
(4) |
Feb
(8) |
Mar
(6) |
Apr
(10) |
May
(2) |
Jun
(3) |
Jul
(11) |
Aug
(10) |
Sep
(4) |
Oct
|
Nov
(1) |
Dec
(1) |
| 2013 |
Jan
(4) |
Feb
(1) |
Mar
(9) |
Apr
(1) |
May
(8) |
Jun
(2) |
Jul
(5) |
Aug
(2) |
Sep
|
Oct
(3) |
Nov
(10) |
Dec
(8) |
| 2014 |
Jan
(3) |
Feb
(12) |
Mar
(9) |
Apr
(12) |
May
(2) |
Jun
|
Jul
(3) |
Aug
(1) |
Sep
(1) |
Oct
(4) |
Nov
|
Dec
(2) |
| 2015 |
Jan
(1) |
Feb
(3) |
Mar
(4) |
Apr
(9) |
May
(2) |
Jun
(2) |
Jul
|
Aug
(2) |
Sep
(7) |
Oct
(9) |
Nov
(7) |
Dec
(9) |
| 2016 |
Jan
(7) |
Feb
(5) |
Mar
(5) |
Apr
(5) |
May
(8) |
Jun
(4) |
Jul
(5) |
Aug
(4) |
Sep
(6) |
Oct
(7) |
Nov
(2) |
Dec
(3) |
| 2017 |
Jan
(7) |
Feb
(8) |
Mar
(7) |
Apr
(3) |
May
(4) |
Jun
(3) |
Jul
(5) |
Aug
(8) |
Sep
(4) |
Oct
(2) |
Nov
(3) |
Dec
|
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2019 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2021 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2022 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
| 2024 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2025 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
(2) |
Aug
(5) |
Sep
(2) |
Oct
|
Nov
|
Dec
(1) |
| 2026 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: jack h. <hij...@ho...> - 2004-10-20 05:29:56
|
Hello Spring team I am now under one project which takes Spring framework and Cocoon webmvc. My question is have you integrate Spring and Cocoon before? If yes, where can I find the resource? Appreciate your time. /Jack _________________________________________________________________ 享用世界上最大的电子邮件系统― MSN Hotmail。 http://www.hotmail.com |
|
From: <jue...@we...> - 2004-10-20 05:13:29
|
Which arguments do you intend to pass in there, for creation of the =
CGLIB proxy? ProxyFactory usually works with an existing target object, =
so doesn't know about the constructor arguments used for creating the =
target object.=20
=20
Does this mean that the application developer would have to specify an =
arbitrary set of arguments that the target class will accept, just to =
get an instance of the CGLIB proxy subclass? That would feel a bit odd.
=20
Juergen
=20
________________________________
Von: spr...@li... im Auftrag =
von Rob Harrop
Gesendet: Mi 20.10.2004 00:18
An: spr...@li...
Betreff: Re: [Springframework-developer] RE: CGLIB memory usage within =
class loader
Jurgen,
The non-default constructor stuff works in the Cglib2AopProxy class but
I need to modify ProxyFactory and ProxyFactoryBean to pass the new args
across to Cglib2AopProxy.
I'll hold fire on new commits until you add yours in.
Rob
j=FCrgen h=F6ller [werk3AT] wrote:
>Rob,
>
>I haven't committed the changes yet, because I need to merge in your =
changes from the afternoon first :-) Will do so tomorrow morning. It =
would probably be good for you to wait until I've committed, to avoid =
any further merging conflicts...
>
>Your recent changes have to do with using non-default constructors on =
CGLIB proxies, as far as I see. Is this already fully working?
>
>Juergen
>
>
>________________________________
>
>Von: spr...@li... im Auftrag =
von Rob Harrop
>Gesendet: Di 19.10.2004 20:04
>An: spr...@li...
>Betreff: Re: [Springframework-developer] RE: CGLIB memory usage within =
class loader
>
>
>
>Jurgen/All,
>
>I'll check into this some more and see if I can reduce the memory usage
>of the proxy classes. On another note I can't see the changes that
>Jurgen has made, I made some changes about two hours ago and they seem
>to have committed.
>
>Rob
>
>j=FCrgen h=F6ller [werk3AT] wrote:
>
>=20
>
>>BTW, I've polished Cglib2AopProxy's source code quite a bit: for =
example, it logs at debug level now (rather than info), and uses =
formatting consistent with the rest of Spring's sources.
>>
>>I've actually already done this polishing a second time: The earlier =
one got lost. It shows up in CVS, but then seems to have got overwritten =
by a subsequent commit. There was also a JDK 1.4 dependency fix in there =
(Boolean.valueOf with a boolean argument), which got lost too.
>>
>>So please, when you merge before a commit, double-check that you're =
not losing updates that someone else applied before you! It wasn't a big =
issue this time, but what if we don't notice it next time...
>>
>>Juergen
>>
>>
>>-----Original Message-----
>>From: j=FCrgen h=F6ller [werk3AT]
>>Sent: Tuesday, October 19, 2004 6:35 PM
>>To: spr...@li...
>>Subject: CGLIB memory usage within class loader
>>
>>
>>I've just been made aware of the following by a werk3 colleague: When =
repeatedly creating CGLIB proxies for the same target class but for =
different advices - within the same class loader -, you'll create new =
proxied classes all the time, which won't get removed for the lifetime =
of the classes.
>>
>>The generated classes themselves are not the problem here. However, =
each of those proxy classes seems to hold strong references to its =
advices and target object, through holding the ProxyCallbackFilter =
instance that was passed into the Enhancer on proxy creation. Note that =
the proxy *class* holds that reference, not the proxy *instance*.
>>
>>The effect is that you can easily run out of memory if your advices or =
target objects occupy a large amount of memory, as none of those objects =
will get garbage collected as long as the CGLIB-generated proxy class is =
still hanging around in the class loader. This does *not* happen at all =
with JDK dynamic proxies.
>>
>>Of course, such excessive proxy creation is not the usual case in a =
production application. Web app restart is not a problem either, as the =
class loader will be shut down (releasing the CGLIB-generated proxy =
classes). The usual scenario where this memory leak becomes a problem is =
test suites, with application contexts getting created per test method.
>>
>>The following code snippet reproduces the issue:
>>
>> while (true) {
>> ProxyFactory proxyFactory =3D new ProxyFactory();
>> proxyFactory.setTarget(new TestBean() {
>> private byte[] field =3D new byte[1000000];
>> });
>> proxyFactory.addAdvice(new DebugInterceptor());
>> proxyFactory.setProxyTargetClass(true);
>> TestBean tb =3D (TestBean) proxyFactory.getProxy();
>> Thread.sleep(100);
>> }
>>
>>Depending on the max memory available to the VM, you'll run into an =
OutOfMemoryError sooner or later, as the target TestBean instance with =
its byte array of size 1000000 never gets garbage collected. Note that =
this does *not* happen when removing the addAdvice call, as we're just =
generating a single CGLIB proxy class then.
>>
>>Is this behavior unavoidable? What do we recommend for such testing =
scenarios then? In particular for integration tests with Hibernate, a 5 =
MB leak per context creation is not really acceptable. Of course it's =
preferable to share the application context as far as possible, but =
there are still valid use cases for repeated creation...
>>
>>Juergen
>>
>>
>>-------------------------------------------------------
>>This SF.net email is sponsored by: IT Product Guide on =
ITManagersJournal
>>Use IT products in your business? Tell us what you think of them. Give =
us
>>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out =
more
>>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>>_______________________________________________
>>Springframework-developer mailing list
>>Spr...@li...
>>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>>
>>
>>
>>
>> =20
>>
>
>
>-------------------------------------------------------
>This SF.net email is sponsored by: IT Product Guide on =
ITManagersJournal
>Use IT products in your business? Tell us what you think of them. Give =
us
>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out =
more
>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
>
>-------------------------------------------------------
>This SF.net email is sponsored by: IT Product Guide on =
ITManagersJournal
>Use IT products in your business? Tell us what you think of them. Give =
us
>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out =
more
>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>=20
>
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give =
us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out =
more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: Guillaume P. <gpo...@gl...> - 2004-10-20 02:10:23
|
> How does it not create a leak if the classloader is not going away? > The real cause of the OOM exceptions is that the WebappClassLoader > instances never go away. I meant if the container (e.g. Tomcat) doesn't throw the ClassLoader away, i.e. if it's still in use... Of course, if the webapp is reloaded and the old ClassLoader isn't collected, that's a leak. What I was saying is the problem with Dom4j cause a leak when you reload the webapp, but cause no leak if you never use hot-reload. (While the CGLIB leak apparently does the opposite) Guillaume ----- Original Message ----- From: "Seth Ladd" <set...@gm...> To: <spr...@li...> Sent: Tuesday, October 19, 2004 7:58 PM Subject: Re: [Springframework-developer] CGLIB memory usage within class loader > On Tue, 19 Oct 2004 18:41:48 -0400, Guillaume Poirier > <gpo...@gl...> wrote: >> > And we still see OOM w/ redeployments in Tomcat. The more I look into >> > it, the more it points to a CGLIB problem from Hibernate. Only when I >> > include Hibernate into my deployments or somehow use CGLIB do I get >> > OOM after a few redeployments or test runs. >> >> If you use Hibernate, then there's at least something else that will >> prevent >> the old webapp's classloader to be collected when you application is >> reloaded. That's Dom4j, it uses ThreadLocal stuff without ever removing >> it, >> which prevent the ClassLoader to be collected for as long as the pooled >> threads are not destroyed. >> >> However, that particular problem doesn't cause any leak if the webapp's >> ClassLoader isn't thrown away. > > How does it not create a leak if the classloader is not going away? > The real cause of the OOM exceptions is that the WebappClassLoader > instances never go away. > > Thanks! > Seth > > > ------------------------------------------------------- > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > Use IT products in your business? Tell us what you think of them. Give us > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out > more > http://productguide.itmanagersjournal.com/guidepromo.tmpl > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer |
|
From: Seth L. <set...@gm...> - 2004-10-19 23:58:22
|
On Tue, 19 Oct 2004 18:41:48 -0400, Guillaume Poirier <gpo...@gl...> wrote: > > And we still see OOM w/ redeployments in Tomcat. The more I look into > > it, the more it points to a CGLIB problem from Hibernate. Only when I > > include Hibernate into my deployments or somehow use CGLIB do I get > > OOM after a few redeployments or test runs. > > If you use Hibernate, then there's at least something else that will prevent > the old webapp's classloader to be collected when you application is > reloaded. That's Dom4j, it uses ThreadLocal stuff without ever removing it, > which prevent the ClassLoader to be collected for as long as the pooled > threads are not destroyed. > > However, that particular problem doesn't cause any leak if the webapp's > ClassLoader isn't thrown away. How does it not create a leak if the classloader is not going away? The real cause of the OOM exceptions is that the WebappClassLoader instances never go away. Thanks! Seth |
|
From: Guillaume P. <gpo...@gl...> - 2004-10-19 22:41:49
|
> And we still see OOM w/ redeployments in Tomcat. The more I look into > it, the more it points to a CGLIB problem from Hibernate. Only when I > include Hibernate into my deployments or somehow use CGLIB do I get > OOM after a few redeployments or test runs. If you use Hibernate, then there's at least something else that will prevent the old webapp's classloader to be collected when you application is reloaded. That's Dom4j, it uses ThreadLocal stuff without ever removing it, which prevent the ClassLoader to be collected for as long as the pooled threads are not destroyed. However, that particular problem doesn't cause any leak if the webapp's ClassLoader isn't thrown away. Guillaume ----- Original Message ----- From: "Seth Ladd" <set...@gm...> To: <spr...@li...> Sent: Tuesday, October 19, 2004 4:06 PM Subject: Re: [Springframework-developer] CGLIB memory usage within class loader > On Tue, 19 Oct 2004 14:05:47 -0400, Rob Rudin <rob...@ur...> wrote: >> Juergen - we found ourselves having the same problem with >> creating contexts per test method, though we weren't using CGLIB >> proxies through Spring. CGLIB was still involved because of >> Hibernate, and we found that the JVM for the integration test >> would run out of memory after about 20-25 tests that each >> created a new context and then did some operations involving >> Hibernate. We ended up extending TestCase and TestSuite so that >> a single context is created and shared among test methods; this >> helped us get around the problem. >> >> We also get this problem when restarting just the webapp in >> Tomcat. I know this was discussed before, and I thought we >> shouldn't be affected because we only use JDK proxies, but it >> still occurs for us. >> >> Is there any chance that this will eventually be fixed in CGLIB? >> We can get by with one context for all test methods, but as you >> state, it would be nice for it not to be a problem when each >> test method does need to create its own context. > > We also have experienced this problem. We had to create one single > ApplicationContext for all tests. Otherwise... BOOM... OOM. > > And we still see OOM w/ redeployments in Tomcat. The more I look into > it, the more it points to a CGLIB problem from Hibernate. Only when I > include Hibernate into my deployments or somehow use CGLIB do I get > OOM after a few redeployments or test runs. > > Seth > > > ------------------------------------------------------- > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > Use IT products in your business? Tell us what you think of them. Give us > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out > more > http://productguide.itmanagersjournal.com/guidepromo.tmpl > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer |
|
From: <al...@jt...> - 2004-10-19 22:32:05
|
<html><head>
<style>
.white { color:#FFFFFF }.index { background-color:#FFFFFF }.index-passed { =
color:#004400 }.index-failed { color:#FF0000; font-weight:bold }.index-head=
er { font-weight:bold }.link { font-family:arial,helvetica,sans-serif; font=
-size:10pt; color:#FFFFFF; text-decoration:none; }.tab-table { margin: 0em =
0em 0.5em 0em; }.tabs { font-family:arial,helvetica,sans-serif; font-size:8=
pt; color:#000000; font-weight:bold; padding: 0em 2em; background-color:#EE=
EEEE; }.tabs-link { color:#000000; text-decoration:none; }.tabs-link:visite=
d { color:#000000; text-decoration:none; }.tabs-selected { font-family:aria=
l,helvetica,sans-serif; font-size:8pt; color:#000000; font-weight:bold; pad=
ding: 0em 2em; }.tabs-selected { border: inset; }.header-title { font-famil=
y:arial,helvetica,sans-serif; font-size:12pt; color:#000000; font-weight:bo=
ld; }.header-label { font-weight:bold; }.header-data { font-family:arial,he=
lvetica,sans-serif; font-size:10pt; color:#000000; }.modifications-data { f=
ont-family:arial,helvetica,sans-serif; font-size:8pt; color:#000000; }.modi=
fications-sectionheader { background-color:#000066; font-family:arial,helve=
tica,sans-serif; font-size:10pt; color:#FFFFFF; }.modifications-oddrow { ba=
ckground-color:#CCCCCC }.modifications-evenrow { background-color:#FFFFCC }=
.changelists-oddrow { background-color:#CCCCCC }.changelists-evenrow { back=
ground-color:#FFFFCC }.changelists-file-spacer { background-color:#FFFFFF }=
.changelists-file-evenrow { background-color:#EEEEEE }.changelists-file-odd=
row { background-color:#FFFFEE }.changelists-file-header { background-color=
:#666666; font-family:arial,helvetica,sans-serif; font-size:8pt; color:#FFF=
FFF; }.compile-data { font-family:arial,helvetica,sans-serif; font-size:8pt=
; color:#000000; }.compile-error-data { font-family:arial,helvetica,sans-se=
rif; font-size:8pt; color:#FF0000; }.compile-warn-data { font-family:arial,=
helvetica,sans-serif; font-size:8pt; color:#CC9900; }.compile-sectionheader=
{ background-color:#000066; font-family:arial,helvetica,sans-serif; font-s=
ize:10pt; color:#FFFFFF; }.distributables-data { font-family:arial,helvetic=
a,sans-serif; font-size:8pt; color:#000000; }.distributables-sectionheader =
{ background-color:#000066; font-family:arial,helvetica,sans-serif; font-si=
ze:10pt; color:#FFFFFF; }.distributables-oddrow { background-color:#CCCCCC =
}.unittests-sectionheader { background-color:#000066; font-family:arial,hel=
vetica,sans-serif; font-size:10pt; color:#FFFFFF; }.unittests-oddrow { back=
ground-color:#CCCCCC }.unittests-data { font-family:arial,helvetica,sans-se=
rif; font-size:8pt; color:#000000; }.unittests-error { font-family:arial,he=
lvetica,sans-serif; font-size:8pt; color:#FF0000; }.checkstyle-oddrow { bac=
kground-color:#CCCCCC }.checkstyle-data { font-family:arial,helvetica,sans-=
serif; font-size:8pt; color:#000000; }.checkstyle-sectionheader { backgroun=
d-color:#000066; font-family:arial,helvetica,sans-serif; font-size:10pt; co=
lor:#FFFFFF; }
</style>
</head><body>
<p>
<table width=3D"98%" border=3D"0" cellspacing=3D"0" cellpadding=3D"2" align=
=3D"center"><tr><td class=3D"header-title">BUILD COMPLETE - =
build.128</td></tr><tr><td class=3D"header-data"><span class=
=3D"header-label">Date of build: </span>10/20/2004 00:16:52</td></tr><=
tr><td class=3D"header-data"><span class=3D"header-label">Time to build:&nb=
sp;</span>13 minutes 23 seconds</td></tr><tr><td class=3D"header-data"><spa=
n class=3D"header-label">Last changed: </span>10/19/2004 18:42:01</td>=
</tr><tr><td class=3D"header-data"><span class=3D"header-label">Last log en=
try: </span>removed misleading constructor-arg comment</td></tr></tabl=
e><p>
<table xmlns=3D"http://www.w3.org/TR/html4/strict.dtd" width=3D"98%" border=
=3D"0" cellspacing=3D"0" cellpadding=3D"2" align=3D"center"/><p>
<p>
<table xmlns=3D"http://www.w3.org/TR/html4/strict.dtd" width=3D"98%" border=
=3D"0" cellspacing=3D"0" cellpadding=3D"2" align=3D"center"><tr><td class=
=3D"compile-sectionheader"> Errors/Warnings: (=
6) </td></tr><tr><td><pre class=3D"compile-error-data">N=
ote: Some input files use or override a deprecated API.<br class=3D"none"/>=
Note: Recompile with -deprecation for details.Note: /jteam/build/checkout/s=
pring/spring/mock/org/springframework/mock/web/MockHttpSession.java uses or=
overrides a deprecated API.<br class=3D"none"/>Note: Recompile with -depre=
cation for details.<br class=3D"none"/>Note: Some input files use or overri=
de a deprecated API.<br class=3D"none"/>Note: Recompile with -deprecation f=
or details.<br class=3D"none"/></pre></td></tr></table><p>
<p>
<table width=3D"98%" border=3D"0" cellspacing=3D"0" cellpadding=3D"2" align=
=3D"center"><tr><td colspan=3D"4" class=3D"unittests-sectionheader"> =
Unit Tests: (1470) </td></tr><tr><td><tabl=
e width=3D"98%" border=3D"0" cellspacing=3D"0" cellpadding=3D"2" align=3D"c=
enter"><tr><td class=3D"unittests-data"> failure =
</td><td width=3D"40%" class=3D"unittests-data">testHomePage</td><td width=
=3D"40%" class=3D"unittests-data">org.springframework.apptests.buildtest.Al=
lTests</td></tr></table></td></tr><tr></tr><tr><td colspan=3D"2"> </td=
></tr><tr><td colspan=3D"4" class=3D"unittests-sectionheader"> =
Unit Test Error Details: (1) </td></tr><tr=
><td class=3D"unittests-data" colspan=3D"2"> Test: test=
HomePage</td></tr><tr><td class=3D"unittests-data" colspan=3D"2"> =
Class: org.springframework.apptests.buildtest.AllTests</td></tr>=
<tr><td class=3D"unittests-data" colspan=3D"2"> Type: junit.=
framework.AssertionFailedError</td></tr><tr><td class=3D"unittests-data" co=
lspan=3D"2"> Message: Exception while testing URL http://loc=
alhost:13084/buildtest:java.io.IOException</td></tr><tr><td class=3D"unitte=
sts-error" colspan=3D"2"><pre>junit.framework.AssertionFailedError: Excepti=
on while testing URL http://localhost:13084/buildtest:java.io.IOException<b=
r>=09at org.springframework.apptests.buildtest.AllTests.testHomePage(Unknow=
n Source)<br>=09at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Meth=
od)<br>=09at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccess=
orImpl.java:39)<br>=09at sun.reflect.DelegatingMethodAccessorImpl.invoke(De=
legatingMethodAccessorImpl.java:25)<br></pre></td></tr><tr><td colspan=3D"2=
"> </td></tr></table><p>
<table width=3D"98%" border=3D"0" cellspacing=3D"0" cellpadding=3D"2" align=
=3D"center"><tr><td colspan=3D"4" class=3D"modifications-sectionheader"> =
Modifications since last build: =
(16) </td></tr><tr class=3D"modifications-evenrow"><td =
class=3D"modifications-data">modified</td><td class=3D"modifications-data">=
jhoeller</td><td class=3D"modifications-data">src/org/springframework/beans=
/factory/xml/spring-beans.dtd</td><td class=3D"modifications-data">removed =
misleading constructor-arg comment</td></tr><tr class=3D"modifications-oddr=
ow"><td class=3D"modifications-data">modified</td><td class=3D"modification=
s-data">jhoeller</td><td class=3D"modifications-data">docs/reference/src/be=
ans.xml</td><td class=3D"modifications-data">fixed typos</td></tr><tr class=
=3D"modifications-evenrow"><td class=3D"modifications-data">modified</td><t=
d class=3D"modifications-data">robharrop</td><td class=3D"modifications-dat=
a">/.classpath</td><td class=3D"modifications-data">Fixed bug SPR-396 in JM=
X sandbox code</td></tr><tr class=3D"modifications-oddrow"><td class=3D"mod=
ifications-data">modified</td><td class=3D"modifications-data">kdonald</td>=
<td class=3D"modifications-data">sandbox/src/org/springframework/util/Cachi=
ngMapTemplate.java</td><td class=3D"modifications-data">simplification</td>=
</tr><tr class=3D"modifications-evenrow"><td class=3D"modifications-data">a=
dded</td><td class=3D"modifications-data">kdonald</td><td class=3D"modifica=
tions-data">sandbox/test/org/springframework/util/CachingMapTemplateTests.j=
ava</td><td class=3D"modifications-data">simplification</td></tr><tr class=
=3D"modifications-oddrow"><td class=3D"modifications-data">modified</td><td=
class=3D"modifications-data">colins</td><td class=3D"modifications-data">d=
ocs/reference/src/beans.xml</td><td class=3D"modifications-data">clarify ho=
w lookup method injection happens.</td></tr><tr class=3D"modifications-even=
row"><td class=3D"modifications-data">modified</td><td class=3D"modificatio=
ns-data">colins</td><td class=3D"modifications-data">docs/reference/src/bea=
ns.xml</td><td class=3D"modifications-data">add documentation on abstract b=
eans</td></tr><tr class=3D"modifications-oddrow"><td class=3D"modifications=
-data">modified</td><td class=3D"modifications-data">robharrop</td><td clas=
s=3D"modifications-data">src/org/springframework/aop/framework/Cglib2AopPro=
xy.java</td><td class=3D"modifications-data">Added additional tests for CGL=
IB proxies</td></tr><tr class=3D"modifications-evenrow"><td class=3D"modifi=
cations-data">modified</td><td class=3D"modifications-data">robharrop</td><=
td class=3D"modifications-data">src/org/springframework/remoting/rmi/JndiRm=
iProxyFactoryBean.java</td><td class=3D"modifications-data">Added additiona=
l tests for CGLIB proxies</td></tr><tr class=3D"modifications-oddrow"><td c=
lass=3D"modifications-data">modified</td><td class=3D"modifications-data">r=
obharrop</td><td class=3D"modifications-data">test/org/springframework/bean=
s/factory/xml/SPR391LookupMethodWrappedByCglibProxyTests.java</td><td class=
=3D"modifications-data">Added additional tests for CGLIB proxies</td></tr><=
tr class=3D"modifications-evenrow"><td class=3D"modifications-data">modifie=
d</td><td class=3D"modifications-data">robharrop</td><td class=3D"modificat=
ions-data">test/org/springframework/aop/framework/CglibProxyTests.java</td>=
<td class=3D"modifications-data">Added additional tests for CGLIB proxies</=
td></tr><tr class=3D"modifications-oddrow"><td class=3D"modifications-data"=
>added</td><td class=3D"modifications-data">robharrop</td><td class=3D"modi=
fications-data">test/org/springframework/aop/framework/NoArgCtorTestBean.ja=
va</td><td class=3D"modifications-data">Added additional tests for CGLIB pr=
oxies</td></tr><tr class=3D"modifications-evenrow"><td class=3D"modificatio=
ns-data">modified</td><td class=3D"modifications-data">robharrop</td><td cl=
ass=3D"modifications-data">test/org/springframework/beans/TestBean.java</td=
><td class=3D"modifications-data">Added additional tests for CGLIB proxies<=
/td></tr><tr class=3D"modifications-oddrow"><td class=3D"modifications-data=
">added</td><td class=3D"modifications-data">johnsonr</td><td class=3D"modi=
fications-data">sandbox/src/org/springframework/beans/factory/Configurer.ja=
va</td><td class=3D"modifications-data">First version: incomplete</td></tr>=
<tr class=3D"modifications-evenrow"><td class=3D"modifications-data">added<=
/td><td class=3D"modifications-data">johnsonr</td><td class=3D"modification=
s-data">sandbox/src/org/springframework/beans/factory/Definition.java</td><=
td class=3D"modifications-data">First version: incomplete</td></tr><tr clas=
s=3D"modifications-oddrow"><td class=3D"modifications-data">added</td><td c=
lass=3D"modifications-data">johnsonr</td><td class=3D"modifications-data">s=
andbox/src/org/springframework/beans/factory/DefinitionImpl.java</td><td cl=
ass=3D"modifications-data">First version: incomplete</td></tr></table><p>
<table width=3D"98%" border=3D"0" cellspacing=3D"0" cellpadding=3D"2" align=
=3D"center"><tr><td class=3D"distributables-sectionheader"> =
Deployments by this build: (8) </td><=
/tr><tr><td class=3D"distributables-data">Building jar: /jteam/build/checko=
ut/spring/spring/dist/spring.jar</td></tr><tr class=3D"distributables-oddro=
w"><td class=3D"distributables-data">Building war: /jteam/build/checkout/sp=
ring/spring/autobuilds/apps/buildtest/dist/buildtest.war</td></tr><tr><td c=
lass=3D"distributables-data">Building war: /jteam/build/checkout/spring/spr=
ing/autobuilds/apps/buildtest/dist/buildtest.war</td></tr><tr class=3D"dist=
ributables-oddrow"><td class=3D"distributables-data">Building war: /jteam/b=
uild/checkout/spring/spring/autobuilds/apps/buildtest/dist/buildtest.war</t=
d></tr><tr><td class=3D"distributables-data">Building jar: /jteam/build/che=
ckout/spring/spring/autobuilds/apps/jpetstore/war/WEB-INF/lib/jpetstore.jar=
</td></tr><tr class=3D"distributables-oddrow"><td class=3D"distributables-d=
ata">Building war: /jteam/build/checkout/spring/spring/autobuilds/apps/jpet=
store/dist/jpetstore.war</td></tr><tr><td class=3D"distributables-data">Bui=
lding jar: /jteam/build/checkout/spring/spring/autobuilds/apps/jpetstore/wa=
r/WEB-INF/lib/jpetstore.jar</td></tr><tr class=3D"distributables-oddrow"><t=
d class=3D"distributables-data">Building war: /jteam/build/checkout/spring/=
spring/autobuilds/apps/jpetstore/dist/jpetstore.war</td></tr></table>
</body></html> |
|
From: Rob H. <ro...@ca...> - 2004-10-19 22:20:16
|
Jurgen,
The non-default constructor stuff works in the Cglib2AopProxy class but
I need to modify ProxyFactory and ProxyFactoryBean to pass the new args
across to Cglib2AopProxy.
I'll hold fire on new commits until you add yours in.
Rob
jürgen höller [werk3AT] wrote:
>Rob,
>
>I haven't committed the changes yet, because I need to merge in your changes from the afternoon first :-) Will do so tomorrow morning. It would probably be good for you to wait until I've committed, to avoid any further merging conflicts...
>
>Your recent changes have to do with using non-default constructors on CGLIB proxies, as far as I see. Is this already fully working?
>
>Juergen
>
>
>________________________________
>
>Von: spr...@li... im Auftrag von Rob Harrop
>Gesendet: Di 19.10.2004 20:04
>An: spr...@li...
>Betreff: Re: [Springframework-developer] RE: CGLIB memory usage within class loader
>
>
>
>Jurgen/All,
>
>I'll check into this some more and see if I can reduce the memory usage
>of the proxy classes. On another note I can't see the changes that
>Jurgen has made, I made some changes about two hours ago and they seem
>to have committed.
>
>Rob
>
>jürgen höller [werk3AT] wrote:
>
>
>
>>BTW, I've polished Cglib2AopProxy's source code quite a bit: for example, it logs at debug level now (rather than info), and uses formatting consistent with the rest of Spring's sources.
>>
>>I've actually already done this polishing a second time: The earlier one got lost. It shows up in CVS, but then seems to have got overwritten by a subsequent commit. There was also a JDK 1.4 dependency fix in there (Boolean.valueOf with a boolean argument), which got lost too.
>>
>>So please, when you merge before a commit, double-check that you're not losing updates that someone else applied before you! It wasn't a big issue this time, but what if we don't notice it next time...
>>
>>Juergen
>>
>>
>>-----Original Message-----
>>From: jürgen höller [werk3AT]
>>Sent: Tuesday, October 19, 2004 6:35 PM
>>To: spr...@li...
>>Subject: CGLIB memory usage within class loader
>>
>>
>>I've just been made aware of the following by a werk3 colleague: When repeatedly creating CGLIB proxies for the same target class but for different advices - within the same class loader -, you'll create new proxied classes all the time, which won't get removed for the lifetime of the classes.
>>
>>The generated classes themselves are not the problem here. However, each of those proxy classes seems to hold strong references to its advices and target object, through holding the ProxyCallbackFilter instance that was passed into the Enhancer on proxy creation. Note that the proxy *class* holds that reference, not the proxy *instance*.
>>
>>The effect is that you can easily run out of memory if your advices or target objects occupy a large amount of memory, as none of those objects will get garbage collected as long as the CGLIB-generated proxy class is still hanging around in the class loader. This does *not* happen at all with JDK dynamic proxies.
>>
>>Of course, such excessive proxy creation is not the usual case in a production application. Web app restart is not a problem either, as the class loader will be shut down (releasing the CGLIB-generated proxy classes). The usual scenario where this memory leak becomes a problem is test suites, with application contexts getting created per test method.
>>
>>The following code snippet reproduces the issue:
>>
>> while (true) {
>> ProxyFactory proxyFactory = new ProxyFactory();
>> proxyFactory.setTarget(new TestBean() {
>> private byte[] field = new byte[1000000];
>> });
>> proxyFactory.addAdvice(new DebugInterceptor());
>> proxyFactory.setProxyTargetClass(true);
>> TestBean tb = (TestBean) proxyFactory.getProxy();
>> Thread.sleep(100);
>> }
>>
>>Depending on the max memory available to the VM, you'll run into an OutOfMemoryError sooner or later, as the target TestBean instance with its byte array of size 1000000 never gets garbage collected. Note that this does *not* happen when removing the addAdvice call, as we're just generating a single CGLIB proxy class then.
>>
>>Is this behavior unavoidable? What do we recommend for such testing scenarios then? In particular for integration tests with Hibernate, a 5 MB leak per context creation is not really acceptable. Of course it's preferable to share the application context as far as possible, but there are still valid use cases for repeated creation...
>>
>>Juergen
>>
>>
>>-------------------------------------------------------
>>This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
>>Use IT products in your business? Tell us what you think of them. Give us
>>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
>>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>>_______________________________________________
>>Springframework-developer mailing list
>>Spr...@li...
>>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>>
>>
>>
>>
>>
>>
>
>
>-------------------------------------------------------
>This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
>Use IT products in your business? Tell us what you think of them. Give us
>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
>
>-------------------------------------------------------
>This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
>Use IT products in your business? Tell us what you think of them. Give us
>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
>
|
|
From: <jue...@we...> - 2004-10-19 21:28:27
|
Rob,
=20
I haven't committed the changes yet, because I need to merge in your =
changes from the afternoon first :-) Will do so tomorrow morning. It =
would probably be good for you to wait until I've committed, to avoid =
any further merging conflicts...
=20
Your recent changes have to do with using non-default constructors on =
CGLIB proxies, as far as I see. Is this already fully working?
=20
Juergen
=20
________________________________
Von: spr...@li... im Auftrag =
von Rob Harrop
Gesendet: Di 19.10.2004 20:04
An: spr...@li...
Betreff: Re: [Springframework-developer] RE: CGLIB memory usage within =
class loader
Jurgen/All,
I'll check into this some more and see if I can reduce the memory usage
of the proxy classes. On another note I can't see the changes that
Jurgen has made, I made some changes about two hours ago and they seem
to have committed.
Rob
j=FCrgen h=F6ller [werk3AT] wrote:
>BTW, I've polished Cglib2AopProxy's source code quite a bit: for =
example, it logs at debug level now (rather than info), and uses =
formatting consistent with the rest of Spring's sources.
>
>I've actually already done this polishing a second time: The earlier =
one got lost. It shows up in CVS, but then seems to have got overwritten =
by a subsequent commit. There was also a JDK 1.4 dependency fix in there =
(Boolean.valueOf with a boolean argument), which got lost too.
>
>So please, when you merge before a commit, double-check that you're not =
losing updates that someone else applied before you! It wasn't a big =
issue this time, but what if we don't notice it next time...
>
>Juergen
>
>
>-----Original Message-----
>From: j=FCrgen h=F6ller [werk3AT]
>Sent: Tuesday, October 19, 2004 6:35 PM
>To: spr...@li...
>Subject: CGLIB memory usage within class loader
>
>
>I've just been made aware of the following by a werk3 colleague: When =
repeatedly creating CGLIB proxies for the same target class but for =
different advices - within the same class loader -, you'll create new =
proxied classes all the time, which won't get removed for the lifetime =
of the classes.
>
>The generated classes themselves are not the problem here. However, =
each of those proxy classes seems to hold strong references to its =
advices and target object, through holding the ProxyCallbackFilter =
instance that was passed into the Enhancer on proxy creation. Note that =
the proxy *class* holds that reference, not the proxy *instance*.
>
>The effect is that you can easily run out of memory if your advices or =
target objects occupy a large amount of memory, as none of those objects =
will get garbage collected as long as the CGLIB-generated proxy class is =
still hanging around in the class loader. This does *not* happen at all =
with JDK dynamic proxies.
>
>Of course, such excessive proxy creation is not the usual case in a =
production application. Web app restart is not a problem either, as the =
class loader will be shut down (releasing the CGLIB-generated proxy =
classes). The usual scenario where this memory leak becomes a problem is =
test suites, with application contexts getting created per test method.
>
>The following code snippet reproduces the issue:
>
> while (true) {
> ProxyFactory proxyFactory =3D new ProxyFactory();
> proxyFactory.setTarget(new TestBean() {
> private byte[] field =3D new byte[1000000];
> });
> proxyFactory.addAdvice(new DebugInterceptor());
> proxyFactory.setProxyTargetClass(true);
> TestBean tb =3D (TestBean) proxyFactory.getProxy();
> Thread.sleep(100);
> }
>
>Depending on the max memory available to the VM, you'll run into an =
OutOfMemoryError sooner or later, as the target TestBean instance with =
its byte array of size 1000000 never gets garbage collected. Note that =
this does *not* happen when removing the addAdvice call, as we're just =
generating a single CGLIB proxy class then.
>
>Is this behavior unavoidable? What do we recommend for such testing =
scenarios then? In particular for integration tests with Hibernate, a 5 =
MB leak per context creation is not really acceptable. Of course it's =
preferable to share the application context as far as possible, but =
there are still valid use cases for repeated creation...
>
>Juergen
>
>
>-------------------------------------------------------
>This SF.net email is sponsored by: IT Product Guide on =
ITManagersJournal
>Use IT products in your business? Tell us what you think of them. Give =
us
>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out =
more
>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>=20
>
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give =
us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out =
more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: <tho...@tr...> - 2004-10-19 21:11:46
|
Rob, Don't know if you've seen this, but there is a free version of JProbe available for download. It's limited to 5 users, and you have to download a new version when it expires in six months. Good enough for home use :) http://www.quest.com/jprobe/profiler_freeware.asp Thomas Quoting Rob Harrop <ro...@ca...>: > To add to what Chris is saying, the best way to keep memory usage is to > implement equals() on your interceptors so that proxy classes can be > reused as much as possible. I am going to look into a solution that will > use weak references from the proxy class but strong references from > proxy instances. This way once a proxy class is no longer used the > advice chain and target can still be GCd. In the rare case when the > advice chain is collected but the proxy class could still apply we can > instruct CGLIB to create a new proxy class anyway - this will > effectively remove this problem in all but the MOST extreme cases. > > I will work on this as soon as I get back to work. I need access to a > profiler to make this solution work properly and I don't have one at home. > > Rob > > Chris Nokleberg wrote: > > >Rob Rudin wrote: > > > > > >>Is there any chance that this will eventually be fixed in CGLIB? > >>We can get by with one context for all test methods, but as you > >>state, it would be nice for it not to be a problem when each > >>test method does need to create its own context. > >> > >> > > > >CGLIB keeps an internal WeakReference-based per-ClassLoader cache of all > >generated classes, and tries to use it whenever possible. But if anything > >about the requested proxy changes, it does the safe thing and generates a > >new class. As Rob Harrop alluded to, for CGLIB to realize that one proxy is > >the same as another, among other things the Callback and CallbackFilter > >objects must implement equals/hashCode properly. Hibernate may have some > >issues in this regard, so you may want to file a bug with them. > > > >Chris > > > > > > > > > >------------------------------------------------------- > >This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > >Use IT products in your business? Tell us what you think of them. Give us > >Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more > >http://productguide.itmanagersjournal.com/guidepromo.tmpl > >_______________________________________________ > >Springframework-developer mailing list > >Spr...@li... > >https://lists.sourceforge.net/lists/listinfo/springframework-developer > > > > > > > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > Use IT products in your business? Tell us what you think of them. Give us > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more > http://productguide.itmanagersjournal.com/guidepromo.tmpl > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer > |
|
From: Rob H. <ro...@ca...> - 2004-10-19 20:52:30
|
I'll look at the Hibernate code as well it may be that proxy classes aren't getting reused as often as possible. Rob Seth Ladd wrote: >On Tue, 19 Oct 2004 14:05:47 -0400, Rob Rudin <rob...@ur...> wrote: > > >>Juergen - we found ourselves having the same problem with >>creating contexts per test method, though we weren't using CGLIB >>proxies through Spring. CGLIB was still involved because of >>Hibernate, and we found that the JVM for the integration test >>would run out of memory after about 20-25 tests that each >>created a new context and then did some operations involving >>Hibernate. We ended up extending TestCase and TestSuite so that >>a single context is created and shared among test methods; this >>helped us get around the problem. >> >>We also get this problem when restarting just the webapp in >>Tomcat. I know this was discussed before, and I thought we >>shouldn't be affected because we only use JDK proxies, but it >>still occurs for us. >> >>Is there any chance that this will eventually be fixed in CGLIB? >>We can get by with one context for all test methods, but as you >>state, it would be nice for it not to be a problem when each >>test method does need to create its own context. >> >> > >We also have experienced this problem. We had to create one single >ApplicationContext for all tests. Otherwise... BOOM... OOM. > >And we still see OOM w/ redeployments in Tomcat. The more I look into >it, the more it points to a CGLIB problem from Hibernate. Only when I >include Hibernate into my deployments or somehow use CGLIB do I get >OOM after a few redeployments or test runs. > >Seth > > >------------------------------------------------------- >This SF.net email is sponsored by: IT Product Guide on ITManagersJournal >Use IT products in your business? Tell us what you think of them. Give us >Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more >http://productguide.itmanagersjournal.com/guidepromo.tmpl >_______________________________________________ >Springframework-developer mailing list >Spr...@li... >https://lists.sourceforge.net/lists/listinfo/springframework-developer > > > > |
|
From: David S. <ds...@mi...> - 2004-10-19 20:19:09
|
OH, that's surprising to me. I missed that comment in the Javadoc which says the same, more or less. I understand the suggested usage pattern better though examples would still be helpful in the javadocs. This leaves me with more commentary: (1) There's still the Object[] parameter values separated from setting the parameter types... though this can be localized to the SqlQuery subclass implementation you suggested. setXXXX (where XXX is a type) style I think is preferred. (2) If it's suggested that client code invoke this specialized method only, then shouldn't most of the methods in RdmsOperation on-up in the hierarchy be protected? Having them public suggests that client code might want to touch them when they shouldn't be. As it stands, if I don't want client code to have visibility of them, I'd need to create a small class that delegates to an SqlQuery instead of extends from it. It'd need to delegate setting the DataSource too. (3) RdbmsOperation claims to be thread-safe but it isn't. compile(), and all getters & setters should employ synchronization. Alternatively, the false thread-safe claim could be eliminated. I wonder what the rest of the Spring community thinks of the SqlQuery hierarchy design. Cheers, Dave Smiley Rod Johnson wrote: > You're meant to subclass SqlQuery to add strongly typed methods with > meaningful names. > > E.g. findAllSomethingOrOthers(int, String) would invoke the generically > typed execute() method in the superclass. > > David Smiley wrote: > >> Hello... I hope it's appropriate to post my comment to this list since >> it's not a usage assistance issue (in which case I'd be sending this >> to the user list). >> >> I just started working on project here that uses Spring jdbc.core's >> JdbcTemplate & the gang in that package. When I discovered the higher >> order abstractions in jdbc.object, it seemed to me that we should use >> those facilities. The lead developer of the project told me that he >> deliberately avoided it because he thought the *untyped* Object[] >> array to parameterize a query as found in SqlQuery.execute() was a >> very poor design choice. He preferred the interface and use of >> PreparedStatementSetter as used within jdbc.core. I tend to agree but I >> still want to use the package anyway. I do see the declareParameter() >> and setTypes() methods of RdbmsOperation but this just separates the >> type determination from specifying the parameter values when it could >> be done at once (again, as with PreparedStatementSetter). Can the >> rationale between the Object[] parameterization in jdbc.object be >> explained, and perhaps could jdbc.object be reworked in the future to >> handle a PreparedStatementSetter or some similar typed parameter >> strategy? >> >> Thanks. >> >> ~ David Smiley >> MITRE >> >> >> >> ------------------------------------------------------- >> This SF.net email is sponsored by: IT Product Guide on ITManagersJournal >> Use IT products in your business? Tell us what you think of them. Give us >> Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out >> more >> http://productguide.itmanagersjournal.com/guidepromo.tmpl >> _______________________________________________ >> Springframework-developer mailing list >> Spr...@li... >> https://lists.sourceforge.net/lists/listinfo/springframework-developer >> > |
|
From: Seth L. <set...@gm...> - 2004-10-19 20:06:11
|
On Tue, 19 Oct 2004 14:05:47 -0400, Rob Rudin <rob...@ur...> wrote: > Juergen - we found ourselves having the same problem with > creating contexts per test method, though we weren't using CGLIB > proxies through Spring. CGLIB was still involved because of > Hibernate, and we found that the JVM for the integration test > would run out of memory after about 20-25 tests that each > created a new context and then did some operations involving > Hibernate. We ended up extending TestCase and TestSuite so that > a single context is created and shared among test methods; this > helped us get around the problem. > > We also get this problem when restarting just the webapp in > Tomcat. I know this was discussed before, and I thought we > shouldn't be affected because we only use JDK proxies, but it > still occurs for us. > > Is there any chance that this will eventually be fixed in CGLIB? > We can get by with one context for all test methods, but as you > state, it would be nice for it not to be a problem when each > test method does need to create its own context. We also have experienced this problem. We had to create one single ApplicationContext for all tests. Otherwise... BOOM... OOM. And we still see OOM w/ redeployments in Tomcat. The more I look into it, the more it points to a CGLIB problem from Hibernate. Only when I include Hibernate into my deployments or somehow use CGLIB do I get OOM after a few redeployments or test runs. Seth |
|
From: Rob H. <ro...@ca...> - 2004-10-19 20:00:25
|
To add to what Chris is saying, the best way to keep memory usage is to implement equals() on your interceptors so that proxy classes can be reused as much as possible. I am going to look into a solution that will use weak references from the proxy class but strong references from proxy instances. This way once a proxy class is no longer used the advice chain and target can still be GCd. In the rare case when the advice chain is collected but the proxy class could still apply we can instruct CGLIB to create a new proxy class anyway - this will effectively remove this problem in all but the MOST extreme cases. I will work on this as soon as I get back to work. I need access to a profiler to make this solution work properly and I don't have one at home. Rob Chris Nokleberg wrote: >Rob Rudin wrote: > > >>Is there any chance that this will eventually be fixed in CGLIB? >>We can get by with one context for all test methods, but as you >>state, it would be nice for it not to be a problem when each >>test method does need to create its own context. >> >> > >CGLIB keeps an internal WeakReference-based per-ClassLoader cache of all >generated classes, and tries to use it whenever possible. But if anything >about the requested proxy changes, it does the safe thing and generates a >new class. As Rob Harrop alluded to, for CGLIB to realize that one proxy is >the same as another, among other things the Callback and CallbackFilter >objects must implement equals/hashCode properly. Hibernate may have some >issues in this regard, so you may want to file a bug with them. > >Chris > > > > >------------------------------------------------------- >This SF.net email is sponsored by: IT Product Guide on ITManagersJournal >Use IT products in your business? Tell us what you think of them. Give us >Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more >http://productguide.itmanagersjournal.com/guidepromo.tmpl >_______________________________________________ >Springframework-developer mailing list >Spr...@li... >https://lists.sourceforge.net/lists/listinfo/springframework-developer > > > > |
|
From: Chris N. <ch...@si...> - 2004-10-19 19:32:50
|
Rob Rudin wrote: > Is there any chance that this will eventually be fixed in CGLIB? > We can get by with one context for all test methods, but as you > state, it would be nice for it not to be a problem when each > test method does need to create its own context. CGLIB keeps an internal WeakReference-based per-ClassLoader cache of all generated classes, and tries to use it whenever possible. But if anything about the requested proxy changes, it does the safe thing and generates a new class. As Rob Harrop alluded to, for CGLIB to realize that one proxy is the same as another, among other things the Callback and CallbackFilter objects must implement equals/hashCode properly. Hibernate may have some issues in this regard, so you may want to file a bug with them. Chris |
|
From: Rob H. <ro...@ca...> - 2004-10-19 18:23:18
|
All,
One note of interest is that wherever possible a proxy class is reused.
In order for a proxy class for the same target class to be resued the
advisors must be equal. In the case Jurgen shows this is not the case -
he uses two instances of DebugInterceptor and the default implementation
of equals() is to use ==. If you override equals() like in
NopInterceptor and equals() returns true for all advisors then the proxy
class will be reused.
Rob
jürgen höller [werk3AT] wrote:
>I've just been made aware of the following by a werk3 colleague: When repeatedly creating CGLIB proxies for the same target class but for different advices - within the same class loader -, you'll create new proxied classes all the time, which won't get removed for the lifetime of the classes.
>
>The generated classes themselves are not the problem here. However, each of those proxy classes seems to hold strong references to its advices and target object, through holding the ProxyCallbackFilter instance that was passed into the Enhancer on proxy creation. Note that the proxy *class* holds that reference, not the proxy *instance*.
>
>The effect is that you can easily run out of memory if your advices or target objects occupy a large amount of memory, as none of those objects will get garbage collected as long as the CGLIB-generated proxy class is still hanging around in the class loader. This does *not* happen at all with JDK dynamic proxies.
>
>Of course, such excessive proxy creation is not the usual case in a production application. Web app restart is not a problem either, as the class loader will be shut down (releasing the CGLIB-generated proxy classes). The usual scenario where this memory leak becomes a problem is test suites, with application contexts getting created per test method.
>
>The following code snippet reproduces the issue:
>
> while (true) {
> ProxyFactory proxyFactory = new ProxyFactory();
> proxyFactory.setTarget(new TestBean() {
> private byte[] field = new byte[1000000];
> });
> proxyFactory.addAdvice(new DebugInterceptor());
> proxyFactory.setProxyTargetClass(true);
> TestBean tb = (TestBean) proxyFactory.getProxy();
> Thread.sleep(100);
> }
>
>Depending on the max memory available to the VM, you'll run into an OutOfMemoryError sooner or later, as the target TestBean instance with its byte array of size 1000000 never gets garbage collected. Note that this does *not* happen when removing the addAdvice call, as we're just generating a single CGLIB proxy class then.
>
>Is this behavior unavoidable? What do we recommend for such testing scenarios then? In particular for integration tests with Hibernate, a 5 MB leak per context creation is not really acceptable. Of course it's preferable to share the application context as far as possible, but there are still valid use cases for repeated creation...
>
>Juergen
>
>
>-------------------------------------------------------
>This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
>Use IT products in your business? Tell us what you think of them. Give us
>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
>
|
|
From: Rod J. <ro...@in...> - 2004-10-19 18:10:33
|
You're meant to subclass SqlQuery to add strongly typed methods with meaningful names. E.g. findAllSomethingOrOthers(int, String) would invoke the generically typed execute() method in the superclass. David Smiley wrote: > Hello... I hope it's appropriate to post my comment to this list since > it's not a usage assistance issue (in which case I'd be sending this to > the user list). > > I just started working on project here that uses Spring jdbc.core's > JdbcTemplate & the gang in that package. When I discovered the higher > order abstractions in jdbc.object, it seemed to me that we should use > those facilities. The lead developer of the project told me that he > deliberately avoided it because he thought the *untyped* Object[] array > to parameterize a query as found in SqlQuery.execute() was a very poor > design choice. He preferred the interface and use of > PreparedStatementSetter as used within jdbc.core. I tend to agree but I > still want to use the package anyway. I do see the declareParameter() > and setTypes() methods of RdbmsOperation but this just separates the > type determination from specifying the parameter values when it could be > done at once (again, as with PreparedStatementSetter). Can the rationale > between the Object[] parameterization in jdbc.object be explained, and > perhaps could jdbc.object be reworked in the future to handle a > PreparedStatementSetter or some similar typed parameter strategy? > > Thanks. > > ~ David Smiley > MITRE > > > > ------------------------------------------------------- > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > Use IT products in your business? Tell us what you think of them. Give us > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more > http://productguide.itmanagersjournal.com/guidepromo.tmpl > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer > -- ____________________________________________________ Rod Johnson Interface21 - Spring Services from the Source http://www.springframework.com Founder, Spring Framework: http://www.springframework.org Author, "Expert One-on-One J2EE Development Without EJB" (May 2004, with Juergen Hoeller). http://www.amazon.com/exec/obidos/ASIN/0764558315/ Author, "Expert One-on-One J2EE Design and Development" (October 2002). http://www.amazon.com/exec/obidos/tg/detail/-/0764543857/ ____________________________________________________ Interface21 Limited Registered Office Summit House, 2-2a Highfield Road, Dartford, Kent DA1 2JY Registered in England and Wales No. 5187766 ____________________________________________________ |
|
From: Rob H. <ro...@ca...> - 2004-10-19 18:06:19
|
Jurgen/All,
I'll check into this some more and see if I can reduce the memory usage
of the proxy classes. On another note I can't see the changes that
Jurgen has made, I made some changes about two hours ago and they seem
to have committed.
Rob
jürgen höller [werk3AT] wrote:
>BTW, I've polished Cglib2AopProxy's source code quite a bit: for example, it logs at debug level now (rather than info), and uses formatting consistent with the rest of Spring's sources.
>
>I've actually already done this polishing a second time: The earlier one got lost. It shows up in CVS, but then seems to have got overwritten by a subsequent commit. There was also a JDK 1.4 dependency fix in there (Boolean.valueOf with a boolean argument), which got lost too.
>
>So please, when you merge before a commit, double-check that you're not losing updates that someone else applied before you! It wasn't a big issue this time, but what if we don't notice it next time...
>
>Juergen
>
>
>-----Original Message-----
>From: jürgen höller [werk3AT]
>Sent: Tuesday, October 19, 2004 6:35 PM
>To: spr...@li...
>Subject: CGLIB memory usage within class loader
>
>
>I've just been made aware of the following by a werk3 colleague: When repeatedly creating CGLIB proxies for the same target class but for different advices - within the same class loader -, you'll create new proxied classes all the time, which won't get removed for the lifetime of the classes.
>
>The generated classes themselves are not the problem here. However, each of those proxy classes seems to hold strong references to its advices and target object, through holding the ProxyCallbackFilter instance that was passed into the Enhancer on proxy creation. Note that the proxy *class* holds that reference, not the proxy *instance*.
>
>The effect is that you can easily run out of memory if your advices or target objects occupy a large amount of memory, as none of those objects will get garbage collected as long as the CGLIB-generated proxy class is still hanging around in the class loader. This does *not* happen at all with JDK dynamic proxies.
>
>Of course, such excessive proxy creation is not the usual case in a production application. Web app restart is not a problem either, as the class loader will be shut down (releasing the CGLIB-generated proxy classes). The usual scenario where this memory leak becomes a problem is test suites, with application contexts getting created per test method.
>
>The following code snippet reproduces the issue:
>
> while (true) {
> ProxyFactory proxyFactory = new ProxyFactory();
> proxyFactory.setTarget(new TestBean() {
> private byte[] field = new byte[1000000];
> });
> proxyFactory.addAdvice(new DebugInterceptor());
> proxyFactory.setProxyTargetClass(true);
> TestBean tb = (TestBean) proxyFactory.getProxy();
> Thread.sleep(100);
> }
>
>Depending on the max memory available to the VM, you'll run into an OutOfMemoryError sooner or later, as the target TestBean instance with its byte array of size 1000000 never gets garbage collected. Note that this does *not* happen when removing the addAdvice call, as we're just generating a single CGLIB proxy class then.
>
>Is this behavior unavoidable? What do we recommend for such testing scenarios then? In particular for integration tests with Hibernate, a 5 MB leak per context creation is not really acceptable. Of course it's preferable to share the application context as far as possible, but there are still valid use cases for repeated creation...
>
>Juergen
>
>
>-------------------------------------------------------
>This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
>Use IT products in your business? Tell us what you think of them. Give us
>Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
>http://productguide.itmanagersjournal.com/guidepromo.tmpl
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
>
|
|
From: Rob R. <rob...@ur...> - 2004-10-19 18:05:53
|
Juergen - we found ourselves having the same problem with
creating contexts per test method, though we weren't using CGLIB
proxies through Spring. CGLIB was still involved because of
Hibernate, and we found that the JVM for the integration test
would run out of memory after about 20-25 tests that each
created a new context and then did some operations involving
Hibernate. We ended up extending TestCase and TestSuite so that
a single context is created and shared among test methods; this
helped us get around the problem.
We also get this problem when restarting just the webapp in
Tomcat. I know this was discussed before, and I thought we
shouldn't be affected because we only use JDK proxies, but it
still occurs for us.
Is there any chance that this will eventually be fixed in CGLIB?
We can get by with one context for all test methods, but as you
state, it would be nice for it not to be a problem when each
test method does need to create its own context.
Rob
---- On Tue, 19 Oct 2004,
=?iso-8859-1?Q?j=FCrgen_h=F6ller_=5Bwerk3AT=5D?=
(jue...@we...) wrote:
> I've just been made aware of the following by a werk3
colleague: When repeatedly creating CGLIB
> proxies for the same target class but for different advices -
within the same class loader -, you'll
> create new proxied classes all the time, which won't get
removed for the lifetime of the classes.
>
> The generated classes themselves are not the problem here.
However, each of those proxy classes seems
> to hold strong references to its advices and target object,
through holding the ProxyCallbackFilter
> instance that was passed into the Enhancer on proxy creation.
Note that the proxy *class* holds that
> reference, not the proxy *instance*.
>
> The effect is that you can easily run out of memory if your
advices or target objects occupy a large
> amount of memory, as none of those objects will get garbage
collected as long as the CGLIB-generated
> proxy class is still hanging around in the class loader. This
does *not* happen at all with JDK
> dynamic proxies.
>
> Of course, such excessive proxy creation is not the usual case
in a production application. Web app
> restart is not a problem either, as the class loader will be
shut down (releasing the CGLIB-generated
> proxy classes). The usual scenario where this memory leak
becomes a problem is test suites, with
> application contexts getting created per test method.
>
> The following code snippet reproduces the issue:
>
> while (true) {
> ProxyFactory proxyFactory = new ProxyFactory();
> proxyFactory.setTarget(new TestBean() {
> private byte[] field = new byte[1000000];
> });
> proxyFactory.addAdvice(new DebugInterceptor());
> proxyFactory.setProxyTargetClass(true);
> TestBean tb = (TestBean) proxyFactory.getProxy();
> Thread.sleep(100);
> }
>
> Depending on the max memory available to the VM, you'll run
into an OutOfMemoryError sooner or later,
> as the target TestBean instance with its byte array of size
1000000 never gets garbage collected.
> Note that this does *not* happen when removing the addAdvice
call, as we're just generating a single
> CGLIB proxy class then.
>
> Is this behavior unavoidable? What do we recommend for such
testing scenarios then? In particular for
> integration tests with Hibernate, a 5 MB leak per context
creation is not really acceptable. Of
> course it's preferable to share the application context as far
as possible, but there are still valid
> use cases for repeated creation...
>
> Juergen
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: IT Product Guide on
ITManagersJournal
> Use IT products in your business? Tell us what you think of
them. Give us
> Your Opinions, Get Free ThinkGeek Gift Certificates! Click to
find out more
> http://productguide.itmanagersjournal.com/guidepromo.tmpl
> _______________________________________________
> Springframework-developer mailing list
> Spr...@li...
>
https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
|
|
From: <jue...@we...> - 2004-10-19 18:02:10
|
I've not committed this yet, as I still need to merge changes in that =
were committed this afternoon ;-)
Juergen
-----Original Message-----
From: j=FCrgen h=F6ller [werk3AT]=20
Sent: Tuesday, October 19, 2004 7:11 PM
To: 'spr...@li...'
Subject: RE: CGLIB memory usage within class loader
BTW, I've polished Cglib2AopProxy's source code quite a bit: for =
example, it logs at debug level now (rather than info), and uses =
formatting consistent with the rest of Spring's sources.
I've actually already done this polishing a second time: The earlier one =
got lost. It shows up in CVS, but then seems to have got overwritten by =
a subsequent commit. There was also a JDK 1.4 dependency fix in there =
(Boolean.valueOf with a boolean argument), which got lost too.
So please, when you merge before a commit, double-check that you're not =
losing updates that someone else applied before you! It wasn't a big =
issue this time, but what if we don't notice it next time...
Juergen
-----Original Message-----
From: j=FCrgen h=F6ller [werk3AT]=20
Sent: Tuesday, October 19, 2004 6:35 PM
To: spr...@li...
Subject: CGLIB memory usage within class loader
I've just been made aware of the following by a werk3 colleague: When =
repeatedly creating CGLIB proxies for the same target class but for =
different advices - within the same class loader -, you'll create new =
proxied classes all the time, which won't get removed for the lifetime =
of the classes.
The generated classes themselves are not the problem here. However, each =
of those proxy classes seems to hold strong references to its advices =
and target object, through holding the ProxyCallbackFilter instance that =
was passed into the Enhancer on proxy creation. Note that the proxy =
*class* holds that reference, not the proxy *instance*.
The effect is that you can easily run out of memory if your advices or =
target objects occupy a large amount of memory, as none of those objects =
will get garbage collected as long as the CGLIB-generated proxy class is =
still hanging around in the class loader. This does *not* happen at all =
with JDK dynamic proxies.
Of course, such excessive proxy creation is not the usual case in a =
production application. Web app restart is not a problem either, as the =
class loader will be shut down (releasing the CGLIB-generated proxy =
classes). The usual scenario where this memory leak becomes a problem is =
test suites, with application contexts getting created per test method.
The following code snippet reproduces the issue:
while (true) {
ProxyFactory proxyFactory =3D new ProxyFactory();
proxyFactory.setTarget(new TestBean() {
private byte[] field =3D new byte[1000000];
});
proxyFactory.addAdvice(new DebugInterceptor());
proxyFactory.setProxyTargetClass(true);
TestBean tb =3D (TestBean) proxyFactory.getProxy();
Thread.sleep(100);
}
Depending on the max memory available to the VM, you'll run into an =
OutOfMemoryError sooner or later, as the target TestBean instance with =
its byte array of size 1000000 never gets garbage collected. Note that =
this does *not* happen when removing the addAdvice call, as we're just =
generating a single CGLIB proxy class then.
Is this behavior unavoidable? What do we recommend for such testing =
scenarios then? In particular for integration tests with Hibernate, a 5 =
MB leak per context creation is not really acceptable. Of course it's =
preferable to share the application context as far as possible, but =
there are still valid use cases for repeated creation...
Juergen
|
|
From: Andy D. <an...@ma...> - 2004-10-19 17:38:01
|
People are beginning to use Spring to do dependency injection and apply=20 aspects (CGLIB) for objects created at runtime (via Hibernate, for example)= =2E =20 Moreover, we have toyed with the idea of applying aspects to objects we=20 dynamically create at runtime to enforce certain security constraints and t= o=20 facilitate distributed object models in a cluster - in which case the aspec= ts=20 are chosen dynamically and could change quite frequently. The dynamic natu= re=20 of all this could land us in the middle of this issue. What would the=20 ramifications be if these proxy classes were modified to use weak reference= s=20 instead of strong? Is this even a possibility? - Andy On Tuesday 19 October 2004 09:35 am, j=FCrgen h=F6ller [werk3AT] wrote: > I've just been made aware of the following by a werk3 colleague: When > repeatedly creating CGLIB proxies for the same target class but for > different advices - within the same class loader -, you'll create new > proxied classes all the time, which won't get removed for the lifetime of > the classes. > > The generated classes themselves are not the problem here. However, each = of > those proxy classes seems to hold strong references to its advices and > target object, through holding the ProxyCallbackFilter instance that was > passed into the Enhancer on proxy creation. Note that the proxy *class* > holds that reference, not the proxy *instance*. |
|
From: David S. <ds...@mi...> - 2004-10-19 17:10:31
|
Hello... I hope it's appropriate to post my comment to this list since it's not a usage assistance issue (in which case I'd be sending this to the user list). I just started working on project here that uses Spring jdbc.core's JdbcTemplate & the gang in that package. When I discovered the higher order abstractions in jdbc.object, it seemed to me that we should use those facilities. The lead developer of the project told me that he deliberately avoided it because he thought the *untyped* Object[] array to parameterize a query as found in SqlQuery.execute() was a very poor design choice. He preferred the interface and use of PreparedStatementSetter as used within jdbc.core. I tend to agree but I still want to use the package anyway. I do see the declareParameter() and setTypes() methods of RdbmsOperation but this just separates the type determination from specifying the parameter values when it could be done at once (again, as with PreparedStatementSetter). Can the rationale between the Object[] parameterization in jdbc.object be explained, and perhaps could jdbc.object be reworked in the future to handle a PreparedStatementSetter or some similar typed parameter strategy? Thanks. ~ David Smiley MITRE |
|
From: <jue...@we...> - 2004-10-19 17:08:36
|
BTW, I've polished Cglib2AopProxy's source code quite a bit: for =
example, it logs at debug level now (rather than info), and uses =
formatting consistent with the rest of Spring's sources.
I've actually already done this polishing a second time: The earlier one =
got lost. It shows up in CVS, but then seems to have got overwritten by =
a subsequent commit. There was also a JDK 1.4 dependency fix in there =
(Boolean.valueOf with a boolean argument), which got lost too.
So please, when you merge before a commit, double-check that you're not =
losing updates that someone else applied before you! It wasn't a big =
issue this time, but what if we don't notice it next time...
Juergen
-----Original Message-----
From: j=FCrgen h=F6ller [werk3AT]=20
Sent: Tuesday, October 19, 2004 6:35 PM
To: spr...@li...
Subject: CGLIB memory usage within class loader
I've just been made aware of the following by a werk3 colleague: When =
repeatedly creating CGLIB proxies for the same target class but for =
different advices - within the same class loader -, you'll create new =
proxied classes all the time, which won't get removed for the lifetime =
of the classes.
The generated classes themselves are not the problem here. However, each =
of those proxy classes seems to hold strong references to its advices =
and target object, through holding the ProxyCallbackFilter instance that =
was passed into the Enhancer on proxy creation. Note that the proxy =
*class* holds that reference, not the proxy *instance*.
The effect is that you can easily run out of memory if your advices or =
target objects occupy a large amount of memory, as none of those objects =
will get garbage collected as long as the CGLIB-generated proxy class is =
still hanging around in the class loader. This does *not* happen at all =
with JDK dynamic proxies.
Of course, such excessive proxy creation is not the usual case in a =
production application. Web app restart is not a problem either, as the =
class loader will be shut down (releasing the CGLIB-generated proxy =
classes). The usual scenario where this memory leak becomes a problem is =
test suites, with application contexts getting created per test method.
The following code snippet reproduces the issue:
while (true) {
ProxyFactory proxyFactory =3D new ProxyFactory();
proxyFactory.setTarget(new TestBean() {
private byte[] field =3D new byte[1000000];
});
proxyFactory.addAdvice(new DebugInterceptor());
proxyFactory.setProxyTargetClass(true);
TestBean tb =3D (TestBean) proxyFactory.getProxy();
Thread.sleep(100);
}
Depending on the max memory available to the VM, you'll run into an =
OutOfMemoryError sooner or later, as the target TestBean instance with =
its byte array of size 1000000 never gets garbage collected. Note that =
this does *not* happen when removing the addAdvice call, as we're just =
generating a single CGLIB proxy class then.
Is this behavior unavoidable? What do we recommend for such testing =
scenarios then? In particular for integration tests with Hibernate, a 5 =
MB leak per context creation is not really acceptable. Of course it's =
preferable to share the application context as far as possible, but =
there are still valid use cases for repeated creation...
Juergen
|
|
From: <jue...@we...> - 2004-10-19 16:33:26
|
I've just been made aware of the following by a werk3 colleague: When =
repeatedly creating CGLIB proxies for the same target class but for =
different advices - within the same class loader -, you'll create new =
proxied classes all the time, which won't get removed for the lifetime =
of the classes.
The generated classes themselves are not the problem here. However, each =
of those proxy classes seems to hold strong references to its advices =
and target object, through holding the ProxyCallbackFilter instance that =
was passed into the Enhancer on proxy creation. Note that the proxy =
*class* holds that reference, not the proxy *instance*.
The effect is that you can easily run out of memory if your advices or =
target objects occupy a large amount of memory, as none of those objects =
will get garbage collected as long as the CGLIB-generated proxy class is =
still hanging around in the class loader. This does *not* happen at all =
with JDK dynamic proxies.
Of course, such excessive proxy creation is not the usual case in a =
production application. Web app restart is not a problem either, as the =
class loader will be shut down (releasing the CGLIB-generated proxy =
classes). The usual scenario where this memory leak becomes a problem is =
test suites, with application contexts getting created per test method.
The following code snippet reproduces the issue:
while (true) {
ProxyFactory proxyFactory =3D new ProxyFactory();
proxyFactory.setTarget(new TestBean() {
private byte[] field =3D new byte[1000000];
});
proxyFactory.addAdvice(new DebugInterceptor());
proxyFactory.setProxyTargetClass(true);
TestBean tb =3D (TestBean) proxyFactory.getProxy();
Thread.sleep(100);
}
Depending on the max memory available to the VM, you'll run into an =
OutOfMemoryError sooner or later, as the target TestBean instance with =
its byte array of size 1000000 never gets garbage collected. Note that =
this does *not* happen when removing the addAdvice call, as we're just =
generating a single CGLIB proxy class then.
Is this behavior unavoidable? What do we recommend for such testing =
scenarios then? In particular for integration tests with Hibernate, a 5 =
MB leak per context creation is not really acceptable. Of course it's =
preferable to share the application context as far as possible, but =
there are still valid use cases for repeated creation...
Juergen
|
|
From: <jue...@we...> - 2004-10-19 16:00:12
|
Alternatively, if you don't mind relying on the class loader, you could = register your own ServletContextListener (after ContextLoaderListener), = which takes the ApplicationContext reference from the ServletContext and = stores it in a custom singleton of yours. As long as your singleton class is loaded by the web app class loader, = this shouldn't cause any issues with other web apps; it relies on the = class loader being specific for the web app. Any code within that web = app could then access the Spring ApplicationContext after startup. Of course, the above is not generally recommended, but it should work. Juergen -----Original Message----- From: spr...@li... [mailto:spr...@li...]On Behalf Of Dion Almaer Sent: Tuesday, October 12, 2004 8:25 PM To: spr...@li... Subject: RE: [Springframework-developer] How to getting at an application context Colin - Thanks for the great info. I will take a peak and see if I can get it working in a fairly simple way. Once you start working with DI it is too painful to have to leave it behind elsewhere! ;) D -----Original Message----- From: Colin Sampaleanu [mailto:col...@ex...]=20 Sent: Tuesday, October 12, 2004 11:57 AM To: spr...@li... Subject: Re: [Springframework-developer] How to getting at an = application context At that point, you're stuck with using some sort of singleton or quasi-singleton, realistically... (which of course is what the servlet context variant is anyways) You can roll your own, or rely on the singleton implementations of BeanFactoryLocator, such as SingletonBeanFactoryLocator or ContextSingletonBeanFactoryLocator. http://www.springframework.org/docs/api/org/springframework/beans/factory= /ac cess/SingletonBeanFactoryLocator.html http://www.springframework.org/docs/api/org/springframework/context/acces= s/C ontextSingletonBeanFactoryLocator.html Note that if you do use these, you will want to probably use a slightly modified setup where you use a service layer appcontext, and the web-app context is just a child of that, and still loaded normally via the = context loader listener. This loading is easily achieved with a subclass of ContextLoader and ContextLoaderListener, like here: http://cvs.sourceforge.net/viewcvs.py/springframework/spring/autobuilds/a= pps /ejbtest/src/java/org/springframework/autobuilds/ejbtest/util/context/Con= tex tLoader.java?view=3Dmarkup http://cvs.sourceforge.net/viewcvs.py/springframework/spring/autobuilds/a= pps /ejbtest/src/java/org/springframework/autobuilds/ejbtest/util/context/Con= tex tLoaderListener.java?view=3Dmarkup Regards, Colin Dion Almaer wrote: >Hi guys - > >When I have code in something like a ServletContextListener I can get=20 >access to the application context easily via: > >ApplicationContext appContext =3D >WebApplicationContextUtils.getWebApplicationContext(event.getServletCon >text( >)); > >However, I have a class that is initiated from third party library,=20 >which is loaded from WEB-INF/lib. > >This third party library has nothing to do with the web, so there is no = >way to get the ServletContext, and hence the application context. > >Is there anyway that I can get from this loaded class to my nice = context? >E.g. can my code look at its ClassLoader and find anything from there? > >Cheers, > >Dion > =20 > ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal = Use IT products in your business? Tell us what you think of them. Give us = Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl _______________________________________________ Springframework-developer mailing list Spr...@li... https://lists.sourceforge.net/lists/listinfo/springframework-developer ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give = us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out = more http://productguide.itmanagersjournal.com/guidepromo.tmpl _______________________________________________ Springframework-developer mailing list Spr...@li... https://lists.sourceforge.net/lists/listinfo/springframework-developer |
|
From: <jue...@we...> - 2004-10-19 13:49:21
|
Such a scenario works nicely for me, with exactly the call order that =
you are using. I've even added a special test case for this, to test a =
minimal scenario.
Can you please double-check that you're not seeing a side effect of =
something else? If you consistently see such behavior, please submit a =
JIRA issue with a minimal test case to reproduce it.
Juergen
-----Original Message-----
From: spr...@li...
[mailto:spr...@li...]On Behalf
Of Andreas Rudolf
Sent: Friday, October 15, 2004 1:13 PM
To: spr...@li...
Subject: [Springframework-developer] Multible singletons
Hi,
no answer so far :-(
Maybe my question wasn't clear enough.
I have two BeanFactories:
parentContext:
<bean id=3D"dao" class=3D"example.DaoImpl"/>
childContext:
<bean id=3D"service" class=3D"example.ServiceImpl"/>
BeanFactory parent =3D new
XMLBeanFactory(parentResource);
Dao dao1 =3D (Dao) parent.getBean("dao");
BeanFactory child =3D new
XMLBeanFactory(childResource,parent);
Dao dao2 =3D (Dao ) child.getBean("dao");
--> Result dao1 and dao2 are NOT the same. I expected
that they must be the same=20
if the bean is defined as a singleton.
In AbstractBeanFactory.geBean(String name, Object[]
args) you don't search a instance in the
singletoncache=20
of the parent beanfactory. Why? Is it an error ?
Regards
Andreas
=09
=09
___________________________________________________________
Gesendet von Yahoo! Mail - Jetzt mit 100MB Speicher kostenlos - Hier =
anmelden: http://mail.yahoo.de
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give =
us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out =
more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|