@@ -54,16 +54,18 @@ public final class PhysicalClassLoader extends URLClassLoader implements Extenda
5454 boolean res = registerAsParallelCapable ();
5555 }
5656
57- private static final double CLASSLOADER_INSPECTION_SIZE = Caster .toIntValue (SystemUtil .getSystemPropOrEnvVar ("lucee.template.classloader.inspection.size" , null ), 2000 );
57+ private static final double CLASSLOADER_INSPECTION_SIZE = Caster .toIntValue (SystemUtil .getSystemPropOrEnvVar ("lucee.template.classloader.inspection.size" , null ), 100 );
58+ private static final double CLASSLOADER_INSPECTION_SIZEBYTES = CLASSLOADER_INSPECTION_SIZE * 1024 * 1024 ;
59+ private static final double CLASSLOADER_INSPECTION_COUNT = Caster .toIntValue (SystemUtil .getSystemPropOrEnvVar ("lucee.template.classloader.inspection.count" , null ), 1000 );
5860 private static final double CLASSLOADER_INSPECTION_RATIO = Caster .toIntValue (SystemUtil .getSystemPropOrEnvVar ("lucee.template.classloader.inspection.ratio" , null ), 3 );
5961
6062 private final Resource directory ;
6163 private ConfigPro config ;
6264 private final ClassLoader addionalClassLoader ;
6365 private final List <Resource > resources ;
6466
65- private Map <String , String > loadedClasses = new ConcurrentHashMap <>();
66- private Map <String , String > allLoadedClasses = new ConcurrentHashMap <>(); // this includes all renames
67+ private Map <String , Integer > loadedClasses = new ConcurrentHashMap <>();
68+ private Map <String , Integer > allLoadedClasses = new ConcurrentHashMap <>(); // this includes all renames
6769 private Map <String , String > unavaiClasses = new ConcurrentHashMap <>();
6870
6971 private PageSourcePool pageSourcePool ;
@@ -109,20 +111,55 @@ public static PhysicalClassLoader flush(PhysicalClassLoader existing, Config con
109111 count += ClazzDynamic .remove (existing );
110112 int all = existing .allLoadedClasses .size ();
111113 int unique = existing .loadedClasses .size ();
112- LogUtil .log (Log .LEVEL_INFO , "physical-classloader" , "flush physical classloader [" + existing .getDirectory () + "] because we reached the size limit (all loaded classes: "
113- + all + "; unique loaded classes: " + unique + "; ratio: " + (all / unique ) + "), removed " + count + " cache elements from dynamic invoker" );
114+ int allClassesBytes = 0 ;
115+ for (Integer i : existing .allLoadedClasses .values ()) {
116+ allClassesBytes += i .intValue ();
117+ }
118+ LogUtil .log (Log .LEVEL_INFO , "physical-classloader" ,
119+ "flush physical classloader [" + existing .getDirectory () + "] because we reached the size limit (all loaded classes count/size: " + all + "/"
120+ + StringUtil .byteFormat (allClassesBytes ) + "; unique loaded classes: " + unique + "; ratio: " + (all / unique ) + "), removed " + count
121+ + " cache elements from dynamic invoker" );
114122
115123 return clone ;
116124 }
117125
118126 public static PhysicalClassLoader flushIfNecessary (PhysicalClassLoader existing , Config config ) {
119127 double all ;
120128
129+ if (LogUtil .does (Log .LEVEL_DEBUG )) {
130+ int allClasses = existing .allLoadedClasses .size ();
131+ int allClassesBytes = 0 ;
132+ int uniqueClasses = existing .loadedClasses .size ();
133+ double ratio = uniqueClasses > 0 ? (double ) allClasses / uniqueClasses : 0 ;
134+
135+ for (Integer i : existing .allLoadedClasses .values ()) {
136+ allClassesBytes += i .intValue ();
137+ }
138+
139+ LogUtil .log (Log .LEVEL_DEBUG , "physical-classloader" ,
140+ "checking if flush necessary for physical classloader [" + existing .getDirectory () + "]: " + "all loaded classes: " + allClasses + " ("
141+ + StringUtil .byteFormat (allClassesBytes ) + "), " + "unique loaded classes: " + uniqueClasses + ", " + "ratio: " + String .format ("%.2f" , ratio ) + ", "
142+ + "inspection size threshold: " + Caster .toString (CLASSLOADER_INSPECTION_COUNT ) + "/" + Caster .toString (CLASSLOADER_INSPECTION_SIZE ) + ", "
143+ + "inspection ratio threshold: " + CLASSLOADER_INSPECTION_RATIO + " - "
144+ + (allClasses > CLASSLOADER_INSPECTION_SIZE
145+ ? (ratio > CLASSLOADER_INSPECTION_RATIO ? "FLUSHING (size and ratio thresholds exceeded)"
146+ : "NOT flushing (ratio " + String .format ("%.2f" , ratio ) + " below threshold " + CLASSLOADER_INSPECTION_RATIO + ")" )
147+ : "NOT flushing (size " + allClasses + " below threshold " + CLASSLOADER_INSPECTION_SIZE + ")" ));
148+ }
149+
121150 // check size
122- if ((all = existing .allLoadedClasses .size ()) > CLASSLOADER_INSPECTION_SIZE ) {
151+ if ((all = existing .allLoadedClasses .size ()) > CLASSLOADER_INSPECTION_COUNT ) {
123152 if ((all / existing .loadedClasses .size ()) > CLASSLOADER_INSPECTION_RATIO ) {
124153 return flush (existing , config );
125154 }
155+
156+ int allClassesBytes = 0 ;
157+ for (Integer i : existing .allLoadedClasses .values ()) {
158+ allClassesBytes += i .intValue ();
159+ }
160+ if (allClassesBytes > CLASSLOADER_INSPECTION_SIZEBYTES ) {
161+ return flush (existing , config );
162+ }
126163 }
127164 return null ;
128165 }
@@ -276,6 +313,13 @@ public Class<?> loadClass(String name, byte[] barr) throws UnmodifiableClassExce
276313 synchronized (getClassLoadingLock (name )) {
277314 Class <?> clazz = findLoadedClass (name );
278315 if (clazz == null ) return _loadClass (name , barr , false );
316+
317+ /*
318+ * Instrumentation instr = InstrumentationFactory.getInstrumentation(config); if (instr != null) {
319+ * try { instr.redefineClasses(new ClassDefinition(clazz, barr)); return clazz; } catch (Exception
320+ * e) { LogUtil.log(InstrumentationFactory.class.getName(), e); } }
321+ */
322+
279323 return rename (clazz , barr );
280324 }
281325 }
@@ -350,8 +394,8 @@ private Class<?> _loadClass(String name, byte[] barr, boolean rename) {
350394 Class <?> clazz = defineClass (name , barr , 0 , barr .length );
351395
352396 if (clazz != null ) {
353- if (!rename ) loadedClasses .put (name , name );
354- allLoadedClasses .put (name , name );
397+ if (!rename ) loadedClasses .put (name , barr . length );
398+ allLoadedClasses .put (name , barr . length );
355399
356400 resolveClass (clazz );
357401 }
0 commit comments