Proxy.isProxyClass scalability

Peter Levart peter.levart at gmail.com
Sat Apr 20 16:37:18 UTC 2013


On 04/20/2013 09:31 AM, Peter Levart wrote:
> Hi Mandy,
>
> I have another idea. Before jumping to implement it, I will first ask 
> what do you think of it. For example:
>
> - have an optimal interface names key calculated from interfaces.
> - visibility of interfaces and other validations are pushed to 
> slow-path (inside ProxyClassFactory.apply)
> - the proxy Class object returned from WeakCache.get() is 
> post-validated with a check like:
>
> for (Class<?> intf : interfaces) {
>     if (!intf.isAssignableFrom(proxyClass)) {
>         throw new IllegalArgumentException();
>     }
> }
> // return post-validated proxyClass from getProxyClass0()...

I just did it:

http://dl.dropboxusercontent.com/u/101777488/jdk8-tl/proxy-wc/webrev.03/index.html

I also incorporated the expunging optimization that I talked about in 
one of previous mails.

And the keys, composed of interface names, are now more space-friendly too:
- a key for 0 interface proxy is a singleton Object
- a key for 1 interface proxy is the name of the interface itself (an 
already interned String)
- a key for 2 interface proxy is a special class with 2 references to 
interned Strings
- a key for 3+ interface proxy is a special class wrapping an array of 
interned Strings

The performance is screaming again (WeakCache+post-validation):


                                         ns/op   WeakCache+ WeakCache+
Test                     Threads     Original   pre-valid. post-valid.
=======================  =======  ===========  =========== ===========
Proxy_getProxyClass            1     2,420.99 2,258.00       211.04
                                4     3,075.39 2,644.26       282.93
                                8     5,374.45 5,159.71       432.14

Proxy_isProxyClassTrue         1        97.75 45.37        42.67
                                4     2,505.92 42.59        42.77
                                8     5,042.61 75.44        73.20

Proxy_isProxyClassFalse        1        89.20 1.40         1.40
                                4     2,548.61 1.40         1.40
                                8     4,901.56 2.82         2.80

Annotation_equals              1       224.39 201.82       202.97
                                4     2,046.21 200.61       204.89
                                8     3,564.78 347.27       344.57


And the space savings are now even greater. Patched code is always 
better space-wise. The savings are:

32 bit addressing:

- 56 bytes per proxy class implementing 1 interface
- 32 bytes per proxy class implementing 2 interfaces
- 16 bytes per proxy class implementing 3 or more interfaces

64 bit addressing:

- 80 bytes per proxy class implementing 1 interface
- 56 bytes per proxy class implementing 2 interfaces
- 24 bytes per proxy class implementing 3 or more interfaces


Regards, Peter


P.S. Details:

32 bit addressing:


    ** Original j.l.r.Proxy
    ** 0 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       400       400
        1         1       760       360
        2         9      1072       312
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 1 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       400       400
        1         1       768       368
        1         2       920       152
        1         3      1072       152
        1         4      1224       152
        1         5      1376       152
        1         6      1528       152
        1         7      1680       152
        1         8      1832       152
        2         9      2152       320
        2        10      2304       152
        2        11      2456       152
        2        12      2672       216
        2        13      2824       152
        2        14      2976       152
        2        15      3128       152
        2        16      3280       152
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 2 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       400       400
        1         1       768       368
        1         2       920       152
        1         3      1072       152
        1         4      1224       152
        1         5      1376       152
        1         6      1528       152
        1         7      1680       152
        1         8      1832       152
        2         9      2152       320
        2        10      2304       152
        2        11      2456       152
        2        12      2672       216
        2        13      2824       152
        2        14      2976       152
        2        15      3128       152
        2        16      3280       152
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 3 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       400       400
        1         1       776       376
        1         2       936       160
        1         3      1096       160
        1         4      1256       160
        1         5      1416       160
        1         6      1576       160
        1         7      1736       160
        1         8      1896       160
        2         9      2224       328
        2        10      2384       160
        2        11      2544       160
        2        12      2768       224
        2        13      2928       160
        2        14      3088       160
        2        15      3248       160
        2        16      3408       160
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 4 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       400       400
        1         1       776       376
        1         2       936       160
        1         3      1096       160
        1         4      1256       160
        1         5      1416       160
        1         6      1576       160
        1         7      1736       160
        1         8      1896       160
        2         9      2224       328
        2        10      2384       160
        2        11      2544       160
        2        12      2768       224
        2        13      2928       160
        2        14      3088       160
        2        15      3248       160
        2        16      3408       160
--------  --------  --------  --------


    ** Patched j.l.r.Proxy
    ** 0 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       240       240
        1         1       768       528
        2         9      1072       304
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 1 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       240       240
        1         1       752       512
        1         2       848        96
        1         3       944        96
        1         4      1040        96
        1         5      1136        96
        1         6      1232        96
        1         7      1328        96
        1         8      1424        96
        2         9      1728       304
        2        10      1824        96
        2        11      1920        96
        2        12      2080       160
        2        13      2176        96
        2        14      2272        96
        2        15      2368        96
        2        16      2464        96
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 2 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       240       240
        1         1       776       536
        1         2       896       120
        1         3      1016       120
        1         4      1136       120
        1         5      1256       120
        1         6      1376       120
        1         7      1496       120
        1         8      1616       120
        2         9      1944       328
        2        10      2064       120
        2        11      2184       120
        2        12      2368       184
        2        13      2488       120
        2        14      2608       120
        2        15      2728       120
        2        16      2848       120
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 3 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       240       240
        1         1       800       560
        1         2       944       144
        1         3      1088       144
        1         4      1232       144
        1         5      1376       144
        1         6      1520       144
        1         7      1664       144
        1         8      1808       144
        2         9      2160       352
        2        10      2304       144
        2        11      2448       144
        2        12      2656       208
        2        13      2800       144
        2        14      2944       144
        2        15      3088       144
        2        16      3232       144
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 4 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       240       240
        1         1       800       560
        1         2       944       144
        1         3      1088       144
        1         4      1232       144
        1         5      1376       144
        1         6      1520       144
        1         7      1664       144
        1         8      1808       144
        2         9      2160       352
        2        10      2304       144
        2        11      2448       144
        2        12      2656       208
        2        13      2800       144
        2        14      2944       144
        2        15      3088       144
        2        16      3232       144
--------  --------  --------  --------


64 bit addressing:


    ** Original j.l.r.Proxy
    ** 0 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       632       632
        1         1      1208       576
        2         9      1728       520
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 1 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       632       632
        1         1      1216       584
        1         2      1448       232
        1         3      1680       232
        1         4      1912       232
        1         5      2144       232
        1         6      2376       232
        1         7      2608       232
        1         8      2840       232
        2         9      3368       528
        2        10      3600       232
        2        11      3832       232
        2        12      4192       360
        2        13      4424       232
        2        14      4656       232
        2        15      4888       232
        2        16      5120       232
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 2 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       632       632
        1         1      1224       592
        1         2      1464       240
        1         3      1704       240
        1         4      1944       240
        1         5      2184       240
        1         6      2424       240
        1         7      2664       240
        1         8      2904       240
        2         9      3440       536
        2        10      3680       240
        2        11      3920       240
        2        12      4288       368
        2        13      4528       240
        2        14      4768       240
        2        15      5008       240
        2        16      5248       240
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 3 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       632       632
        1         1      1232       600
        1         2      1480       248
        1         3      1728       248
        1         4      1976       248
        1         5      2224       248
        1         6      2472       248
        1         7      2720       248
        1         8      2968       248
        2         9      3512       544
        2        10      3760       248
        2        11      4008       248
        2        12      4384       376
        2        13      4632       248
        2        14      4880       248
        2        15      5128       248
        2        16      5376       248
--------  --------  --------  --------

    ** Original j.l.r.Proxy
    ** 4 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       632       632
        1         1      1240       608
        1         2      1496       256
        1         3      1752       256
        1         4      2008       256
        1         5      2264       256
        1         6      2520       256
        1         7      2776       256
        1         8      3032       256
        2         9      3584       552
        2        10      3840       256
        2        11      4096       256
        2        12      4480       384
        2        13      4736       256
        2        14      4992       256
        2        15      5248       256
        2        16      5504       256
--------  --------  --------  --------


    ** Patched j.l.r.Proxy
    ** 0 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       336       336
        1         1      1216       880
        2         9      1720       504
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 1 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       336       336
        1         1      1200       864
        1         2      1352       152
        1         3      1504       152
        1         4      1656       152
        1         5      1808       152
        1         6      1960       152
        1         7      2112       152
        1         8      2264       152
        2         9      2768       504
        2        10      2920       152
        2        11      3072       152
        2        12      3352       280
        2        13      3504       152
        2        14      3656       152
        2        15      3808       152
        2        16      3960       152
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 2 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       336       336
        1         1      1232       896
        1         2      1416       184
        1         3      1600       184
        1         4      1784       184
        1         5      1968       184
        1         6      2152       184
        1         7      2336       184
        1         8      2520       184
        2         9      3056       536
        2        10      3240       184
        2        11      3424       184
        2        12      3736       312
        2        13      3920       184
        2        14      4104       184
        2        15      4288       184
        2        16      4472       184
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 3 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       336       336
        1         1      1272       936
        1         2      1496       224
        1         3      1720       224
        1         4      1944       224
        1         5      2168       224
        1         6      2392       224
        1         7      2616       224
        1         8      2840       224
        2         9      3416       576
        2        10      3640       224
        2        11      3864       224
        2        12      4216       352
        2        13      4440       224
        2        14      4664       224
        2        15      4888       224
        2        16      5112       224
--------  --------  --------  --------

    ** Patched j.l.r.Proxy
    ** 4 interfaces / proxy class

    class     proxy   size of  delta to
  loaders   classes    caches  prev.ln.
--------  --------  --------  --------
        0         0       336       336
        1         1      1280       944
        1         2      1512       232
        1         3      1744       232
        1         4      1976       232
        1         5      2208       232
        1         6      2440       232
        1         7      2672       232
        1         8      2904       232
        2         9      3488       584
        2        10      3720       232
        2        11      3952       232
        2        12      4312       360
        2        13      4544       232
        2        14      4776       232
        2        15      5008       232
        2        16      5240       232
--------  --------  --------  --------


On 04/20/2013 09:31 AM, Peter Levart wrote:
> Hi Mandy,
>
> I have another idea. Before jumping to implement it, I will first ask 
> what do you think of it. For example:
>
> - have an optimal interface names key calculated from interfaces.
> - visibility of interfaces and other validations are pushed to 
> slow-path (inside ProxyClassFactory.apply)
> - the proxy Class object returned from WeakCache.get() is 
> post-validated with a check like:
>
> for (Class<?> intf : interfaces) {
>     if (!intf.isAssignableFrom(proxyClass)) {
>         throw new IllegalArgumentException();
>     }
> }
> // return post-validated proxyClass from getProxyClass0()...
>
> I feel that Class.isAssignableFrom(Class) check could be much faster 
> and that the only reason the check can fail is if some interface is 
> not visible from the class loader.
>
> Am I correct?
>
> Regards, Peter
>
>
>
> On 04/19/2013 04:36 PM, Peter Levart wrote:
>> Hi Mandy,
>>
>> On 04/19/2013 07:33 AM, Mandy Chung wrote:
>>>>
>>>> https://dl.dropboxusercontent.com/u/101777488/jdk8-tl/proxy-wc/webrev.02/index.html 
>>>>
>>>> What about package-private in java.lang.reflect? It makes Proxy 
>>>> itself much easier to read. When we decide which way to go, I can 
>>>> remove the interface and only leave a single package-private class...
>>>>
>>>
>>> thanks.  Moving it to a single package-private classin 
>>> java.lang.reflectand remove the interface sounds good.
>>
>> Right.
>>
>>>
>>> I have merged your patch with the recent TL repo and did some clean 
>>> up while reviewing it.  Some comments:
>>> 1. getProxyClass0 should validate the input interfaces and throw IAE 
>>> if any illegal argument (e.g. interfaces are not visible to the 
>>> given loader) before calling proxyClassCache.get(loader, 
>>> interfaces). I moved back the validation code from 
>>> ProxyClassFactory.apply to getProxyClass0.
>>
>> Ops, you're right. There could be a request with interface(s) with 
>> same name(s) but loaded by different loader(s) and such code could 
>> return wrong pre-cached proxy class instead of throwing exception. 
>> Unfortunately, moving validation to slow-path was the cause of major 
>> performance and scalability improvement observed. With validation 
>> moved back to getProxyClass0 (in spite of using two-level WeakCache), 
>> we have the following performance (WeakCache#1):
>>
>>
>> Summary (4 Cores x 2 Threads i7 CPU):
>>
>> Test                     Threads  ns/op Original WeakCache#1
>> =======================  =======  ============== ===========
>> Proxy_getProxyClass            1        2,403.27 2,174.51
>>                                4        3,039.01 2,555.00
>>                                8        5,193.58 4,273.42
>>
>> Proxy_isProxyClassTrue         1           95.02 43.14
>>                                4        2,266.29 43.23
>>                                8        4,782.29 72.06
>>
>> Proxy_isProxyClassFalse        1           95.02 1.36
>>                                4        2,186.59 1.36
>>                                8        4,891.15 2.72
>>
>> Annotation_equals              1          240.10 195.68
>>                                4        1,864.06 201.41
>>                                8        8,639.20 337.46
>>
>> It's a little better than original getProxyClass(), but not much. The 
>> isProxyClass() and consequently Annotation.equals() are far better 
>> though. But as you might have guessed, I kind of solved that too...
>>
>> My first attempt was to optimize the interface validation. Only the 
>> "visibility" part is necessary to be performed on fast-path. 
>> Uniqueness and other things can be performed on slow-path. With 
>> split-validation and hacks like:
>>
>>     private static final MethodHandle findLoadedClass0MH, 
>> findBootstrapClassMH;
>>     private static final ClassLoader dummyCL = new ClassLoader() {};
>>
>>     static {
>>         try {
>>             Method method = 
>> ClassLoader.class.getDeclaredMethod("findLoadedClass0", String.class);
>>             method.setAccessible(true);
>>             findLoadedClass0MH = 
>> MethodHandles.lookup().unreflect(method);
>>
>>             method = 
>> ClassLoader.class.getDeclaredMethod("findBootstrapClass", String.class);
>>             method.setAccessible(true);
>>             findBootstrapClassMH = 
>> MethodHandles.lookup().unreflect(method);
>>         } catch (NoSuchMethodException e) {
>>             throw (Error) new 
>> NoSuchMethodError(e.getMessage()).initCause(e);
>>         } catch (IllegalAccessException e) {
>>             throw (Error) new 
>> IllegalAccessError(e.getMessage()).initCause(e);
>>         }
>>     }
>>
>>     static Class<?> findLoadedClass(ClassLoader loader, String name) {
>>         try {
>>             if (VM.isSystemDomainLoader(loader)) {
>>                 return (Class<?>) 
>> findBootstrapClassMH.invokeExact(dummyCL, name);
>>             } else {
>>                 return (Class<?>) 
>> findLoadedClass0MH.invokeExact(loader, name);
>>             }
>>         } catch (RuntimeException | Error e) {
>>             throw e;
>>         } catch (Throwable t) {
>>             throw new UndeclaredThrowableException(t);
>>         }
>>     }
>>
>>
>> ... using findLoadedClass(loader, intf.getName()) and only doing 
>> Class.forName(intf.getName(), false, loader) if the former returned 
>> null ... I managed to reclaim some performance (WeakCache#1+):
>>
>>
>> Test                     Threads  ns/op Original  WeakCache#1 
>> WeakCache#1+
>> =======================  =======  ============== =========== 
>> ============
>> Proxy_getProxyClass            1        2,403.27 2,174.51 1,589.36
>>                                4        3,039.01 2,555.00 1,929.11
>>                                8        5,193.58 4,273.42 3,409.77
>>
>>
>> ...but that was still not very satisfactory.
>>
>> I modified the KeyFactory to create keys that weakly-reference 
>> interface Class objects and implement hashCode/equals in terms of 
>> comparing those Class objects. With such keys, no false aliasing can 
>> occur and the whole validation can be pushed back to slow-path. I 
>> tried hard to create keys with as little space overhead as possible:
>>
>> http://dl.dropboxusercontent.com/u/101777488/jdk8-tl/proxy-wc-wi/webrev.01/index.html 
>>
>>
>> ...but there can be no miracles. The good news is that the 
>> performance is back (WeakCache#2):
>>
>>
>> Summary (4 Cores x 2 Threads i7 CPU):
>>
>> Test                     Threads  ns/op Original WeakCache#1 WeakCache#2
>> =======================  =======  ============== =========== ===========
>> Proxy_getProxyClass            1        2,403.27 2,174.51 163.57
>>                                4        3,039.01 2,555.00 211.70
>>                                8        5,193.58 4,273.42 322.14
>>
>> Proxy_isProxyClassTrue         1           95.02 43.14 41.23
>>                                4        2,266.29 43.23 42.20
>>                                8        4,782.29 72.06 72.21
>>
>> Proxy_isProxyClassFalse        1           95.02 1.36 1.36
>>                                4        2,186.59 1.36 1.36
>>                                8        4,891.15 2.72 2.72
>>
>> Annotation_equals              1          240.10 195.68 194.61
>>                                4        1,864.06 201.41 198.81
>>                                8        8,639.20 337.46 342.90
>>
>>
>> ... and the most common usage (proxy class implementing exactly one 
>> interface) uses even less space than with interface-names-key - 16 
>> bytes saved per proxy class vs. 8 bytes saved (32 bit addressing mode):
>>
>> --------------------------------------
>>       Original j.l.r.Proxy
>>       1 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       400       400
>>        1         1       768       368
>>        1         2       920       152
>>        1         3      1072       152
>>        1         4      1224       152
>>        1         5      1376       152
>>        1         6      1528       152
>>        1         7      1680       152
>>        1         8      1832       152
>>        2         9      2152       320
>>        2        10      2304       152
>>        2        11      2456       152
>>        2        12      2672       216
>>        2        13      2824       152
>>        2        14      2976       152
>>        2        15      3128       152
>>        2        16      3280       152
>>
>> --------------------------------------
>>       Patched j.l.r.Proxy
>>       1 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       240       240
>>        1         1       792       552
>>        1         2       928       136
>>        1         3      1064       136
>>        1         4      1200       136
>>        1         5      1336       136
>>        1         6      1472       136
>>        1         7      1608       136
>>        1         8      1744       136
>>        2         9      2088       344
>>        2        10      2224       136
>>        2        11      2360       136
>>        2        12      2560       200
>>        2        13      2696       136
>>        2        14      2832       136
>>        2        15      2968       136
>>        2        16      3104       136
>>
>>
>> Did you know, that Proxy.getProxyClass() can generate proxy classes 
>> implementing 0 interfaces? It can. There's exactly one such class 
>> generated per class loader:
>>
>>
>> --------------------------------------
>>       Original j.l.r.Proxy
>>       0 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       400       400
>>        1         1       760       360
>>        2         2      1072       312
>>
>> --------------------------------------
>>       Patched j.l.r.Proxy
>>       0 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       240       240
>>        1         1       728       488
>>        2         2      1040       312
>>
>>
>> With 2 or more interfaces implemented by proxy class the space 
>> overhead increases faster than with original Proxy:
>>
>>
>> --------------------------------------
>>       Original j.l.r.Proxy
>>       2 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       400       400
>>        1         1       768       368
>>        1         2       920       152
>>        1         3      1072       152
>>        1         4      1224       152
>>        1         5      1376       152
>>        1         6      1528       152
>>        1         7      1680       152
>>        1         8      1832       152
>>        2         9      2152       320
>>        2        10      2304       152
>>        2        11      2456       152
>>        2        12      2672       216
>>        2        13      2824       152
>>        2        14      2976       152
>>        2        15      3128       152
>>        2        16      3280       152
>>
>> --------------------------------------
>>       Patched j.l.r.Proxy
>>       2 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       240       240
>>        1         1       832       592
>>        1         2      1008       176
>>        1         3      1184       176
>>        1         4      1360       176
>>        1         5      1536       176
>>        1         6      1712       176
>>        1         7      1888       176
>>        1         8      2064       176
>>        2         9      2448       384
>>        2        10      2624       176
>>        2        11      2800       176
>>        2        12      3040       240
>>        2        13      3216       176
>>        2        14      3392       176
>>        2        15      3568       176
>>        2        16      3744       176
>>
>> --------------------------------------
>>       Original j.l.r.Proxy
>>       3 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       400       400
>>        1         1       776       376
>>        1         2       936       160
>>        1         3      1096       160
>>        1         4      1256       160
>>        1         5      1416       160
>>        1         6      1576       160
>>        1         7      1736       160
>>        1         8      1896       160
>>        2         9      2224       328
>>        2        10      2384       160
>>        2        11      2544       160
>>        2        12      2768       224
>>        2        13      2928       160
>>        2        14      3088       160
>>        2        15      3248       160
>>        2        16      3408       160
>>
>> --------------------------------------
>>       Patched j.l.r.Proxy
>>       3 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       240       240
>>        1         1       864       624
>>        1         2      1072       208
>>        1         3      1280       208
>>        1         4      1488       208
>>        1         5      1696       208
>>        1         6      1904       208
>>        1         7      2112       208
>>        1         8      2320       208
>>        2         9      2736       416
>>        2        10      2944       208
>>        2        11      3152       208
>>        2        12      3424       272
>>        2        13      3632       208
>>        2        14      3840       208
>>        2        15      4048       208
>>        2        16      4256       208
>>
>> --------------------------------------
>>       Original j.l.r.Proxy
>>       4 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       400       400
>>        1         1       776       376
>>        1         2       936       160
>>        1         3      1096       160
>>        1         4      1256       160
>>        1         5      1416       160
>>        1         6      1576       160
>>        1         7      1736       160
>>        1         8      1896       160
>>        2         9      2224       328
>>        2        10      2384       160
>>        2        11      2544       160
>>        2        12      2768       224
>>        2        13      2928       160
>>        2        14      3088       160
>>        2        15      3248       160
>>        2        16      3408       160
>>
>> --------------------------------------
>>       Patched j.l.r.Proxy
>>       4 interfaces / proxy class
>>
>> class     proxy     size of   delta to
>> loaders   classes   caches    prev.ln.
>> --------  --------  --------  --------
>>        0         0       240       240
>>        1         1       896       656
>>        1         2      1136       240
>>        1         3      1376       240
>>        1         4      1616       240
>>        1         5      1856       240
>>        1         6      2096       240
>>        1         7      2336       240
>>        1         8      2576       240
>>        2         9      3024       448
>>        2        10      3264       240
>>        2        11      3504       240
>>        2        12      3808       304
>>        2        13      4048       240
>>        2        14      4288       240
>>        2        15      4528       240
>>        2        16      4768       240
>>
>>
>> There's an increase of 8 bytes per proxy class key for each 2 
>> interfaces added to proxy class in original Proxy code, but there's 
>> an increase of 32 bytes per proxy class key for each single interface 
>> added in patched Proxy code.
>>
>> I think the most common usage is to implement a single interface and 
>> there is 16 bytes gained for each such usage compared to original 
>> Proxy code.
>>
>>> 2. I did some cleanup to restore some original comments to make the 
>>> diffs clearer where the change is.
>>> 3. I removed the newInstance method which is dead code after my 
>>> previous code.  Since we are in this code, I took the chance to 
>>> clean that up and also change a couple for-loop to use for-each.
>>>
>>> I have put the merged and slightly modified Proxy.java and webrev at:
>>> http://cr.openjdk.java.net/~mchung/jdk8/webrevs/7123493/webrev.00/
>>>
>>> We will use this bug for your contribution:
>>>    7123493 : (proxy) Proxy.getProxyClass doesn't scale under high load
>>
>> I took j.l.r.Proxy file from your webrev and just changed the 
>> KeyFactory implementation. WeakCache is generic and can be used 
>> unchanged with either implementation of KeyFactory.
>>
>>>
>>> For the weak cache class, since it's for proxy implementation use, I 
>>> suggest to take out the supportContainsValueOperation flagas it 
>>> always keeps the reverse map for isProxyClass lookup.
>>>
>>> You can simply call Objects.requireNonNull(param) instead of 
>>> requireNonNull(param, "param-name") since the proxy implementation 
>>> should have made sure the argument is non-null.
>>>
>>> Formatting nits:
>>>
>>>   68         Object cacheKey = CacheKey.valueOf(
>>>   69             key,
>>>   70             refQueue
>>>   71         );
>>>
>>> should be: all in one line or line break on a long-line.  Same for
>>> method signature.
>>>
>>>  237         void expungeFrom(
>>>  238             ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
>>>  239             ConcurrentMap<?, Boolean> reverseMap
>>>  240         );
>>>
>>> should be:
>>>
>>> void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
>>>                  ConcurrentMap<?, Boolean> reverseMap);
>>>
>>> so that it'll be more consistent with the existing code.  I'll do a
>>> detailed review on the weak cache class as you will finalize the code
>>> per the decision to go with the two-level weak cache.
>>
>> I hope I have addressed all that in above webrev.
>>
>> Regards, Peter
>>
>>>
>>> Thanks again for the good work.
>>>
>>> Mandy
>>> [1] http://openjdk.java.net/jeps/161 
>>
>




More information about the core-libs-dev mailing list