URLStreamHandler.getHostAddress() performance
Peter Levart
peter.levart at gmail.com
Thu Nov 27 20:17:32 UTC 2014
Hi,
Some time ago I dived into the sinchronization pitfalls of URL /
URLStreamHandler and came up with a possible solution. Here's the thread
(mostly just my comments) and a patch:
http://mail.openjdk.java.net/pipermail/net-dev/2014-July/008592.html
Regards, Peter
On 11/25/2014 03:03 PM, Mark Sheppard wrote:
> I think this raises a more fundamental question, as to why the URL
> hashCode() and equals() methods delegates to URLStreamHandler
> in the first place? rather than performing the processing within the
> URL class itself, and synchronizing appropriately within.
>
> If you call equals() and hasCode() concurrently on the same URL
> instance, there exists the possibility (slight) that
> the hostAddress could be set differently, when it is being set for the
> first time, without the synchronization of the getHostAddress() in the
> URLStreamHandler.
>
> Although it may rarely happen the mechanics of InetAddress.getByName()
> potentially, lend itself to a different return address
> on multiple calls, as it returns the first address from a array of
> addresses retrieved - assumption is that the ordering will always be
> the same.
>
> regards
> Mark
>
> On 25/11/2014 12:58, Wang Weijun wrote:
>>> On Nov 25, 2014, at 20:25, Pavel Rappo <pavel.rappo at oracle.com> wrote:
>>>
>>> Hi Max,
>>>
>>> I don't see any particular reason for this. Maybe it's just a
>>> "precaution". It seems to me it's the only field
>>> of the URL class set directly (without setter) from an outside.
>>>
>>> Does it hurt performance a lot? In what cases?
>> There is a 7x difference in my experiment on
>> SecureClassLoader.defineClass().
>>
>> Or, it can be shown using this benchmark:
>>
>> package org.openjdk.bench;
>>
>> import org.openjdk.jmh.annotations.*;
>>
>> import java.io.IOException;
>> import java.net.URL;
>> import java.util.*;
>> import java.util.concurrent.ConcurrentHashMap;
>>
>> @State(Scope.Benchmark)
>> public class Weird {
>> final int num = 100;
>> final Object[] urls = new Object[num];
>>
>> public static class CS {
>> private final Object url;
>> public CS(Object url) { this.url = url; }
>> public int hashCode() { return url.hashCode(); }
>> public boolean equals(Object o) { return o instanceof CS &&
>> url.equals(((CS)o).url); }
>> }
>>
>> private final Map<Object, Object> pdcacheC = new
>> ConcurrentHashMap<>();
>>
>> @Setup
>> public void init() throws Exception {
>> for (int i=0; i< num; i++) {
>> urls[i] = new URL("file:/tmp/"+i);
>> }
>> }
>>
>> @State(Scope.Thread)
>> public static class ThreadState {
>> final Random rand = new Random();
>> }
>>
>>
>> @Benchmark
>> public void setC(ThreadState state) throws IOException {
>> Object cs = new CS(urls[next(state)]);
>> pdcacheC.computeIfAbsent(cs, x -> "");
>> }
>>
>> private int next(ThreadState state) {
>> return state.rand.nextInt(num);
>> }
>> }
>>
>> --Max
>>
>>
>>> -Pavel
>>>
>>>> On 25 Nov 2014, at 12:02, Wang Weijun <weijun.wang at oracle.com> wrote:
>>>>
>>>> I am benchmarking security manager and notice this
>>>>
>>>> protected synchronized InetAddress getHostAddress(URL u) {
>>>> if (u.hostAddress != null)
>>>> return u.hostAddress;
>>>>
>>>> String host = u.getHost();
>>>> if (host == null || host.equals("")) {
>>>> return null;
>>>> } else {
>>>> try {
>>>> u.hostAddress = InetAddress.getByName(host);
>>>> } catch (UnknownHostException ex) {
>>>> return null;
>>>> } catch (SecurityException se) {
>>>> return null;
>>>> }
>>>> }
>>>> return u.hostAddress;
>>>> }
>>>>
>>>> Is there any reason why the method is synchronized? Why not simply
>>>> "synchronized (u)"?
>>>>
>>>> Thanks
>>>> Max
>>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20141127/ac1b7879/attachment.htm>
More information about the security-dev
mailing list