Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-28 Thread Peter Levart



On 01/25/2016 05:14 PM, Alan Bateman wrote:



On 25/01/2016 15:27, Peter Levart wrote:


But let me ask something. Doesn't GC processing require (at least in 
some phases) that user threads be stopped in a safepoint? What 
happens when a user thread is blocked by kernel on memory access? 
Such thread can't be stopped in a safepoint. Safepoint can't begin, 
so GC can't proceed and therefore can't promote objects to old 
generation at that time. Am I right? If yes, then time does not pass 
for objects while a user thread is blocked on memory access, so they 
won't get promoted to old gen any time sooner after the user thread 
is unblocked.
With memory mapping then it's very possible that a memory access to 
stall waiting for pages to be faulted in. So yes, I assume any 
STW/safepoint is going to be stall. On the other hand then threads 
doing file or socket I/O on these buffers will be in native (maybe 
blocked, maybe not) and so aren't an issue. They will safepoint on 
return or if they attempt to re-enter.


-Alan


Ah, yes. I/O with direct buffers. All the places that use 
sun.nio.ch.DirectBuffer.address() to obtain address of DB and then 
access the memory directly would also have to obtain current guard from 
DB and keep it until after the last access to the memory. There are 28 
such usages in JDK.


Usages with blocking I/O could use a different strategy. They could use 
reference counting directly (invoke increment/decrement on the 
Deallocator's guardCount and deallocate when it drops to 0). I/O is 
usually invoked for bulk transfers, so adding an atomic increment and 
decrement of an int variable would not present too much overhead for 
such usages, I think.



Regards, Peter



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-28 Thread Peter Levart

Hi,

On 01/25/2016 08:32 PM, Gil Tene wrote:

I assume your goal here is to get the resources released with the next newgen 
collections (following a close()), rather than wait for an oldgen (if the 
resource was held by an old object). That's a cool thing.

With that in mind, you can replace the repeated periodic 
polling/flipping/allocation and external calling changeGuard() with a simple 
internal GC-detecor that would call changeGuard() allocate a new guard only 
once per newgen GC cycle.

This can take the form of adding a simple GCDetector inside your implementation:

private class GCDetector {
 @Override
 protected void finalize() throws Throwable {
 GCDetector detector = new GCDetector();
 changeGuard();
 Reference.reachabilityFence(detector);
 }
}

// The reason to use finalize here instead of a phantom ref
// based cleaner is that it would trigger immediately after the cycle,
// rather than potentially take an extra cycle to trigger.
// This can be done with a weakRef based cleaner instead
// (but probably when one is added to the JDK, otherwise you'd
// need your own polling thread and logic here...).


Good idea. This will adapt the rate of guard changing to the rate of GC 
and there's no need for special executor. A phantom-ref cleaner would be 
equally prompt as finalize(). When there's a finalze() method on the 
referent, finalize() method is invoked 1st, then the FinalReference to 
the referent is cleared and only after that the PhantomReference to the 
same referent can be processed in the next GC cycle. But when there's no 
final() method on the referent, PhantomReference is processed right away.


Also, when a finalize() method creates new finalizable object that has a 
finalize() method which creates new finalizable object that has a 
finalize()  method ...


public class Test {

static class GCDetector {
@Override
protected void finalize() throws Throwable {
System.out.println("GC detected: " + this);
new GCDetector();
}
}

public static void main(String[] args) throws Exception {
System.runFinalizersOnExit(true);
new GCDetector();
}
}

...and you set to run finalizers on exit, you get a never-ending loop 
and VM doesn't exit:


...
GC detected: Test$GCDetector@1088249a
GC detected: Test$GCDetector@7e73ecc
GC detected: Test$GCDetector@4da49a96
GC detected: Test$GCDetector@667a971f
GC detected: Test$GCDetector@3787d3be
...


So a phantom-ref cleaner would work better here. The function of 
Deallocator and guard-changer can even be merged in the same object, so 
guard-changing and reference tracking can be performed by the same 
Cleaner(s) like in:


http://cr.openjdk.java.net/~plevart/misc/CloseableMemory/v2/CloseableMemory.java



Regards, Peter



You'll need to allocate a single instance of GCDetector during construction of a 
CloseableMemory, without retaining a reference to it after construction. This will start 
a finalize-triggering chain per instance, with the chain "ticking" once per 
newgen cycle.

If you want to avoid having one of these (coming and going on each GC cycle) 
per CloseableMemory instance, you can use a common static detector and a 
registration mechanism (where each registered instance would have it's 
changeGuard() method call…

— Gil.



On Jan 24, 2016, at 9:10 AM, Peter Levart  wrote:

Hi,

I had an idea recently on how to expedite the collection of an object. It is 
simple - just don't let it live long.

Here's a concept prototype:

http://cr.openjdk.java.net/~plevart/misc/CloseableMemory/CloseableMemory.java

The overhead of the check in access methods (getByte()/setByte()) amounts to 
one volatile read of an oop variable that changes once per say 5 to 10 seconds. 
That's the period a special guard object is alive. It's reachability is tracked 
by the GC and extends to the end of each access method (using 
Reference.reachabilityFence). Every few seconds, the guard object is changed 
with new fresh one so that the chance of the guard and its tracking Cleaner 
being promoted to old generation is very low.

Could something like that enable a low-overhead CloseableMappedByteBuffer?

Regards, Peter

On 01/23/2016 09:31 PM, Andrew Haley wrote:

On 23/01/16 20:01, Uwe Schindler wrote:


It depends how small! If the speed is still somewhere between Java 8
ByteBuffer performance and the recent Hotspot improvements in Java
9, I agree with trying it out. But some volatile memory access on
every access is a no-go. The code around ByteBufferIndexInput in
Lucene is the most performance-critical critical code, because on
every search query or sorting there is all the work happening in
there (millions of iterations with positional ByteBuffer.get*
calls). As ByteBuffers are limited to 2 GiB, we also need lots of
hairy code to work around that limitation!

Yes, I see that code.  It would be helpful if there were a
self-contained but realistic benchmark using

Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-28 Thread Chris Hegarty
Uwe,

On 28 Jan 2016, at 11:28, Uwe Schindler  wrote:

> Hi,
> 
> Could you update the JIRA issue 
> (https://bugs.openjdk.java.net/browse/JDK-8132928) and JEP 260 
> (http://openjdk.java.net/jeps/260) about the change we discussed here 
> (jdk.internal.ref.Cleaner now implements Runable to support Lucene and 
> similar apps needing to hack into cleaner), mainly in the section "open 
> issues”?

You are still in unsupported waters. You are using reflection and 
setAccessible(true)
to gain access to the internals of direct buffer. The refactoring we are doing 
in
Cleaner as part of this issue, has a positive side-effect, from a library 
maintainers
point of view ( less reflective code and static usage of internal types), but 
this is not
to be confused with an agreed upon supported interface. It is just to keep 
things
working, as we refactor / move some internal types in the JDK. Longer term a
standard Java SE API should replace this.

JEP 260 will, for the present time, continue to list sun.misc.Cleaner as an open
issue, until we are satisfied that there is no critical need for it, outside of 
the 
direct/mapped buffer usage.

> Maybe also add a comment to the source at the "@Override public void run()" 
> decl, so it may not get lost by later refactorings (if somebody thinks 
> "WTF!?")
> 
> The update of above docs would be fine for us to have some reference point to 
> cite when we implement the changed Hack. BTW, we already have a preliminary 
> patch for Lucene (untested): 
> https://issues.apache.org/jira/secure/attachment/12784516/LUCENE-6989.patch

Thanks for doing this Uwe.  I really appreciate your feedback and prompt
replies on this topic.

-Chris.

> Thanks for taking care of this issue.
> Uwe
> 
> -
> Uwe Schindler
> uschind...@apache.org 
> ASF Member, Apache Lucene PMC / Committer
> Bremen, Germany
> http://lucene.apache.org/
> 
>> -Original Message-
>> From: Uwe Schindler [mailto:uschind...@apache.org]
>> Sent: Tuesday, January 26, 2016 5:49 PM
>> To: 'Chris Hegarty' ; 'Alan Bateman'
>> ; 'Roger Riggs' ;
>> uschind...@apache.org
>> Cc: 'core-libs-dev' 
>> Subject: RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
>> 
>> Hi,
>> 
>> API changes l and security check look good to me. I don't have time to
>> compile and test a JDK, but I trust you that it works :-)
>> 
>> Uwe
>> 
>> -
>> Uwe Schindler
>> uschind...@apache.org
>> ASF Member, Apache Lucene PMC / Committer
>> Bremen, Germany
>> http://lucene.apache.org/
>> 
>>> -Original Message-
>>> From: Chris Hegarty [mailto:chris.hega...@oracle.com]
>>> Sent: Tuesday, January 26, 2016 5:28 PM
>>> To: Alan Bateman ; Roger Riggs
>>> ; uschind...@apache.org
>>> Cc: core-libs-dev 
>>> Subject: Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
>>> 
>>> Latest webrev updated in-place:
>>>  http://cr.openjdk.java.net/~chegar/8148117/
>>> 
>>> * to execute the run method requires an appropriate permission
>>> * reverted any copyright changes ( leave to a bulk update )
>>> * updated the test to remove the script
>>> 
>>> -Chris.
>>> 
>>> 
>>> On 26 Jan 2016, at 15:23, Alan Bateman 
>> wrote:
>>> 
>>>> On 26/01/2016 13:55, Chris Hegarty wrote:
>>>>> It is wonderful to see the various ideas on this thread about the longer
>>>>> term solution to the prompt releasing of direct buffer native memory. I
>>>>> do not want to obstruct that ( it is very informative ), but I’d like to 
>>>>> warp
>>> up
>>>>> the review on the actual moving of Cleaner. To that end, I’ve update the
>>>>> webrev as per Alan’s comments and suggestion ( to extend Runnable ).
>>>>> 
>>>>> http://cr.openjdk.java.net/~chegar/8148117/
>>>>> 
>>>>> -Chris.
>>>>> 
>>>>> 
>>>> This looks okay. As a defensive-in-depth then Cleaner::run can do a
>>> permission check and should ease concerns about leakage.
>>> 
> 
> 



RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-28 Thread Uwe Schindler
Hi,

Could you update the JIRA issue 
(https://bugs.openjdk.java.net/browse/JDK-8132928) and JEP 260 
(http://openjdk.java.net/jeps/260) about the change we discussed here 
(jdk.internal.ref.Cleaner now implements Runable to support Lucene and similar 
apps needing to hack into cleaner), mainly in the section "open issues"?

Maybe also add a comment to the source at the "@Override public void run()" 
decl, so it may not get lost by later refactorings (if somebody thinks "WTF!?")

The update of above docs would be fine for us to have some reference point to 
cite when we implement the changed Hack. BTW, we already have a preliminary 
patch for Lucene (untested): 
https://issues.apache.org/jira/secure/attachment/12784516/LUCENE-6989.patch

Thanks for taking care of this issue.
Uwe

-
Uwe Schindler
uschind...@apache.org 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/

> -Original Message-
> From: Uwe Schindler [mailto:uschind...@apache.org]
> Sent: Tuesday, January 26, 2016 5:49 PM
> To: 'Chris Hegarty' ; 'Alan Bateman'
> ; 'Roger Riggs' ;
> uschind...@apache.org
> Cc: 'core-libs-dev' 
> Subject: RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
> 
> Hi,
> 
> API changes l and security check look good to me. I don't have time to
> compile and test a JDK, but I trust you that it works :-)
> 
> Uwe
> 
> -
> Uwe Schindler
> uschind...@apache.org
> ASF Member, Apache Lucene PMC / Committer
> Bremen, Germany
> http://lucene.apache.org/
> 
> > -Original Message-
> > From: Chris Hegarty [mailto:chris.hega...@oracle.com]
> > Sent: Tuesday, January 26, 2016 5:28 PM
> > To: Alan Bateman ; Roger Riggs
> > ; uschind...@apache.org
> > Cc: core-libs-dev 
> > Subject: Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
> >
> > Latest webrev updated in-place:
> >   http://cr.openjdk.java.net/~chegar/8148117/
> >
> >  * to execute the run method requires an appropriate permission
> >  * reverted any copyright changes ( leave to a bulk update )
> >  * updated the test to remove the script
> >
> > -Chris.
> >
> >
> > On 26 Jan 2016, at 15:23, Alan Bateman 
> wrote:
> >
> > > On 26/01/2016 13:55, Chris Hegarty wrote:
> > >> It is wonderful to see the various ideas on this thread about the longer
> > >> term solution to the prompt releasing of direct buffer native memory. I
> > >> do not want to obstruct that ( it is very informative ), but I’d like to 
> > >> warp
> > up
> > >> the review on the actual moving of Cleaner. To that end, I’ve update the
> > >> webrev as per Alan’s comments and suggestion ( to extend Runnable ).
> > >>
> > >> http://cr.openjdk.java.net/~chegar/8148117/
> > >>
> > >> -Chris.
> > >>
> > >>
> > > This looks okay. As a defensive-in-depth then Cleaner::run can do a
> > permission check and should ease concerns about leakage.
> >




Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Mandy Chung

> On Jan 26, 2016, at 8:27 AM, Chris Hegarty  wrote:
> 
> Latest webrev updated in-place:
>  http://cr.openjdk.java.net/~chegar/8148117/
> 
> * to execute the run method requires an appropriate permission
> * reverted any copyright changes ( leave to a bulk update )
> * updated the test to remove the script

Catching up on this review thread.

The patch looks good.  Having jdk.internal.ref.Cleaner to implement Runnable 
with the permission check looks reasonable.

Mandy

Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Alan Bateman



On 26/01/2016 16:27, Chris Hegarty wrote:

Latest webrev updated in-place:
   http://cr.openjdk.java.net/~chegar/8148117/

  * to execute the run method requires an appropriate permission
  * reverted any copyright changes ( leave to a bulk update )
  * updated the test to remove the script

-Chris.


This version looks good to me.

-Alan.


RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Uwe Schindler
Hi,

API changes l and security check look good to me. I don't have time to compile 
and test a JDK, but I trust you that it works :-)

Uwe

-
Uwe Schindler
uschind...@apache.org 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/

> -Original Message-
> From: Chris Hegarty [mailto:chris.hega...@oracle.com]
> Sent: Tuesday, January 26, 2016 5:28 PM
> To: Alan Bateman ; Roger Riggs
> ; uschind...@apache.org
> Cc: core-libs-dev 
> Subject: Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
> 
> Latest webrev updated in-place:
>   http://cr.openjdk.java.net/~chegar/8148117/
> 
>  * to execute the run method requires an appropriate permission
>  * reverted any copyright changes ( leave to a bulk update )
>  * updated the test to remove the script
> 
> -Chris.
> 
> 
> On 26 Jan 2016, at 15:23, Alan Bateman  wrote:
> 
> > On 26/01/2016 13:55, Chris Hegarty wrote:
> >> It is wonderful to see the various ideas on this thread about the longer
> >> term solution to the prompt releasing of direct buffer native memory. I
> >> do not want to obstruct that ( it is very informative ), but I’d like to 
> >> warp
> up
> >> the review on the actual moving of Cleaner. To that end, I’ve update the
> >> webrev as per Alan’s comments and suggestion ( to extend Runnable ).
> >>
> >> http://cr.openjdk.java.net/~chegar/8148117/
> >>
> >> -Chris.
> >>
> >>
> > This looks okay. As a defensive-in-depth then Cleaner::run can do a
> permission check and should ease concerns about leakage.
> 




Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Chris Hegarty
Latest webrev updated in-place:
  http://cr.openjdk.java.net/~chegar/8148117/

 * to execute the run method requires an appropriate permission
 * reverted any copyright changes ( leave to a bulk update )
 * updated the test to remove the script

-Chris.


On 26 Jan 2016, at 15:23, Alan Bateman  wrote:

> On 26/01/2016 13:55, Chris Hegarty wrote:
>> It is wonderful to see the various ideas on this thread about the longer
>> term solution to the prompt releasing of direct buffer native memory. I
>> do not want to obstruct that ( it is very informative ), but I’d like to 
>> warp up
>> the review on the actual moving of Cleaner. To that end, I’ve update the
>> webrev as per Alan’s comments and suggestion ( to extend Runnable ).
>> 
>> http://cr.openjdk.java.net/~chegar/8148117/
>> 
>> -Chris.
>> 
>> 
> This looks okay. As a defensive-in-depth then Cleaner::run can do a 
> permission check and should ease concerns about leakage.





Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Chris Hegarty
On 26 Jan 2016, at 16:36, Roger Riggs  wrote:

> Hi Chris,
> 
> Looks good, thanks for updating the test.
> 
> One typo:   
> "Unexpected exist 
> code”

D’oh. Fixed in-place.

-Chris

> Roger
> 
> 
> 
> On 1/26/2016 11:27 AM, Chris Hegarty wrote:
>> Latest webrev updated in-place:
>>   
>> http://cr.openjdk.java.net/~chegar/8148117/
>> 
>> 
>>  * to execute the run method requires an appropriate permission
>>  * reverted any copyright changes ( leave to a bulk update )
>>  * updated the test to remove the script
>> 
>> -Chris.
>> 
>> 
>> On 26 Jan 2016, at 15:23, Alan Bateman 
>> 
>>  wrote:
>> 
>> 
>>> On 26/01/2016 13:55, Chris Hegarty wrote:
>>> 
 It is wonderful to see the various ideas on this thread about the longer
 term solution to the prompt releasing of direct buffer native memory. I
 do not want to obstruct that ( it is very informative ), but I’d like to 
 warp up
 the review on the actual moving of Cleaner. To that end, I’ve update the
 webrev as per Alan’s comments and suggestion ( to extend Runnable ).
 
 
 http://cr.openjdk.java.net/~chegar/8148117/
 
 
 -Chris.
 
 
 
>>> This looks okay. As a defensive-in-depth then Cleaner::run can do a 
>>> permission check and should ease concerns about leakage.
>>> 
>> 
>> 
>> 
> 



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Roger Riggs

Hi Chris,

Looks good, thanks for updating the test.

One typo:

"Unexpected *exist *code" Roger


On 1/26/2016 11:27 AM, Chris Hegarty wrote:

Latest webrev updated in-place:
   http://cr.openjdk.java.net/~chegar/8148117/

  * to execute the run method requires an appropriate permission
  * reverted any copyright changes ( leave to a bulk update )
  * updated the test to remove the script

-Chris.


On 26 Jan 2016, at 15:23, Alan Bateman  wrote:


On 26/01/2016 13:55, Chris Hegarty wrote:

It is wonderful to see the various ideas on this thread about the longer
term solution to the prompt releasing of direct buffer native memory. I
do not want to obstruct that ( it is very informative ), but I’d like to warp up
the review on the actual moving of Cleaner. To that end, I’ve update the
webrev as per Alan’s comments and suggestion ( to extend Runnable ).

http://cr.openjdk.java.net/~chegar/8148117/

-Chris.



This looks okay. As a defensive-in-depth then Cleaner::run can do a permission 
check and should ease concerns about leakage.







Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Alan Bateman

On 26/01/2016 13:55, Chris Hegarty wrote:

It is wonderful to see the various ideas on this thread about the longer
term solution to the prompt releasing of direct buffer native memory. I
do not want to obstruct that ( it is very informative ), but I’d like to warp up
the review on the actual moving of Cleaner. To that end, I’ve update the
webrev as per Alan’s comments and suggestion ( to extend Runnable ).

http://cr.openjdk.java.net/~chegar/8148117/

-Chris.


This looks okay. As a defensive-in-depth then Cleaner::run can do a 
permission check and should ease concerns about leakage.


-Alan.


Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Roger Riggs

Hi Chris,

Looks fine.

Perhaps update the copyrights.

Upgrading the shell based test to java based would be good sometime too.

Also, there is a more recent version of webrev [1] that provides 
convenient next and previous links.


Thanks, Roger

[1] http://hg.openjdk.java.net/code-tools/webrev/raw-file/tip/webrev.ksh


On 1/26/2016 8:55 AM, Chris Hegarty wrote:

It is wonderful to see the various ideas on this thread about the longer
term solution to the prompt releasing of direct buffer native memory. I
do not want to obstruct that ( it is very informative ), but I’d like to warp up
the review on the actual moving of Cleaner. To that end, I’ve update the
webrev as per Alan’s comments and suggestion ( to extend Runnable ).

http://cr.openjdk.java.net/~chegar/8148117/

-Chris.

On 23 Jan 2016, at 16:36, Alan Bateman  wrote:


On 23/01/2016 16:16, Chris Hegarty wrote:

:

Webrev:
   http://cr.openjdk.java.net/~chegar/8148117/



This has to move to your patch looks okay. You might need to update the 
TEST.groups to ensure that the existOnThrow tests will be run by jdk_core.

-Alan.




RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Uwe Schindler
Hi,

> On 26/01/2016 14:05, Uwe Schindler wrote:
> > Hi,
> >
> > looks good to me. Once we have EA builds with that I will adapt the
> ByteBufferIndexInput code in Lucene.
> >
> > One thing about the Runable: This should work perfectly fine, because we
> only need to make call the getCleaner() method accessible, call it and finally
> check if return type implements Runable (if not we fall back to pre Java 9
> code). We can then cast and invoke the cleaner without any further
> reflection.
> >
> > But there is now some security related issue: The reflection on DirectBuffer
> should work in most environments (also with security managers), so you can
> get the Cleaner instance with a doPrivileged (ideally). But as this cleaner
> instance was previously inside sun.misc package, and you needed
> RuntimePermission "accessInPackage.sun.misc" to call and make the clean
> method accessible. But with the new patch you no longer need this
> permission, making it easier to invoke that method.
> >
> This is a private field so if you are hacking into it then you'll need
> ReflectPermission("suppressAccessChecks") when running with a security
> manager. Clearly anything with a reference to a Cleaner needs to be
> super careful not to let it leak to untrusted code.

I know and Lucene takes care of that. 

I just said, previously you needed both runtime permissions: 
"accessInPackage.sun.misc" AND "suppressAccessChecks", now only one. I just 
suggested to add the 2nd hurdle back somehow, as additional safety.

Otherwise I am fine with the patch, was just meant as "improvement". E.g., 
Elasticsearch already gives *only* lucene-core.jar both permisisions, nothing 
else in its code!!!

Uwe



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Alan Bateman



On 26/01/2016 14:05, Uwe Schindler wrote:

Hi,

looks good to me. Once we have EA builds with that I will adapt the 
ByteBufferIndexInput code in Lucene.

One thing about the Runable: This should work perfectly fine, because we only 
need to make call the getCleaner() method accessible, call it and finally check 
if return type implements Runable (if not we fall back to pre Java 9 code). We 
can then cast and invoke the cleaner without any further reflection.

But there is now some security related issue: The reflection on DirectBuffer should work 
in most environments (also with security managers), so you can get the Cleaner instance 
with a doPrivileged (ideally). But as this cleaner instance was previously inside 
sun.misc package, and you needed RuntimePermission "accessInPackage.sun.misc" 
to call and make the clean method accessible. But with the new patch you no longer need 
this permission, making it easier to invoke that method.

This is a private field so if you are hacking into it then you'll need 
ReflectPermission("suppressAccessChecks") when running with a security 
manager. Clearly anything with a reference to a Cleaner needs to be 
super careful not to let it leak to untrusted code.


-Alan



RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Uwe Schindler
Hi,

looks good to me. Once we have EA builds with that I will adapt the 
ByteBufferIndexInput code in Lucene.

One thing about the Runable: This should work perfectly fine, because we only 
need to make call the getCleaner() method accessible, call it and finally check 
if return type implements Runable (if not we fall back to pre Java 9 code). We 
can then cast and invoke the cleaner without any further reflection.

But there is now some security related issue: The reflection on DirectBuffer 
should work in most environments (also with security managers), so you can get 
the Cleaner instance with a doPrivileged (ideally). But as this cleaner 
instance was previously inside sun.misc package, and you needed 
RuntimePermission "accessInPackage.sun.misc" to call and make the clean method 
accessible. But with the new patch you no longer need this permission, making 
it easier to invoke that method.

In my opinion, you should add some other runtime permission for safety, which 
is checked on calling the run() method. This would make it safe, because as 
soon as you have SecurityManager you would need to give explicit permission to 
the code.

Uwe

-
Uwe Schindler
uschind...@apache.org 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/


> -Original Message-
> From: core-libs-dev [mailto:core-libs-dev-boun...@openjdk.java.net] On
> Behalf Of Chris Hegarty
> Sent: Tuesday, January 26, 2016 2:56 PM
> To: Alan Bateman ; core-libs-dev  d...@openjdk.java.net>
> Subject: Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
> 
> It is wonderful to see the various ideas on this thread about the longer
> term solution to the prompt releasing of direct buffer native memory. I
> do not want to obstruct that ( it is very informative ), but I’d like to warp 
> up
> the review on the actual moving of Cleaner. To that end, I’ve update the
> webrev as per Alan’s comments and suggestion ( to extend Runnable ).
> 
> http://cr.openjdk.java.net/~chegar/8148117/
> 
> -Chris.
> 
> On 23 Jan 2016, at 16:36, Alan Bateman  wrote:
> 
> > On 23/01/2016 16:16, Chris Hegarty wrote:
> >> :
> >>
> >> Webrev:
> >>   http://cr.openjdk.java.net/~chegar/8148117/
> >>
> >>
> > This has to move to your patch looks okay. You might need to update the
> TEST.groups to ensure that the existOnThrow tests will be run by jdk_core.
> >
> > -Alan.



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Paul Sandoz

> On 23 Jan 2016, at 21:31, Andrew Haley  wrote:
> 
> BTW, does anyone here know why we don't have humongous ByteBuffers
> with a long index?
> 

Probably in part because of Java arrays. IMO we need Arrays 2.0 (+ panama i 
suspect).

Here’s some "shoot from the hip" thinking…

In principle a direct ByteBuffer could bound a region larger than that which 
can be expressed with an int limit (i suppose a heap ByteBuffer could do the 
same if it holds multiple instances if byte[], although that would require more 
work).

The direct BB can be used to access the first 2^31 - 1 values. A VarHandle 
could be produced that accesses the whole range since it could accept long 
index values and check bounds against a special long limit field. That might 
require some additional HotSpot work to optimize bounds checks and any loops to 
reduce or avoid a safe point check per iteration.

Paul.


Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-26 Thread Chris Hegarty
It is wonderful to see the various ideas on this thread about the longer
term solution to the prompt releasing of direct buffer native memory. I
do not want to obstruct that ( it is very informative ), but I’d like to warp 
up 
the review on the actual moving of Cleaner. To that end, I’ve update the
webrev as per Alan’s comments and suggestion ( to extend Runnable ).

http://cr.openjdk.java.net/~chegar/8148117/

-Chris.

On 23 Jan 2016, at 16:36, Alan Bateman  wrote:

> On 23/01/2016 16:16, Chris Hegarty wrote:
>> :
>> 
>> Webrev:
>>   http://cr.openjdk.java.net/~chegar/8148117/
>> 
>> 
> This has to move to your patch looks okay. You might need to update the 
> TEST.groups to ensure that the existOnThrow tests will be run by jdk_core.
> 
> -Alan.



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-25 Thread Gil Tene
I assume your goal here is to get the resources released with the next newgen 
collections (following a close()), rather than wait for an oldgen (if the 
resource was held by an old object). That's a cool thing.

With that in mind, you can replace the repeated periodic 
polling/flipping/allocation and external calling changeGuard() with a simple 
internal GC-detecor that would call changeGuard() allocate a new guard only 
once per newgen GC cycle.

This can take the form of adding a simple GCDetector inside your implementation:

private class GCDetector {
@Override
protected void finalize() throws Throwable {
GCDetector detector = new GCDetector();
changeGuard();
Reference.reachabilityFence(detector);
}
}

// The reason to use finalize here instead of a phantom ref
// based cleaner is that it would trigger immediately after the cycle,
// rather than potentially take an extra cycle to trigger.
// This can be done with a weakRef based cleaner instead
// (but probably when one is added to the JDK, otherwise you'd
// need your own polling thread and logic here...).

You'll need to allocate a single instance of GCDetector during construction of 
a CloseableMemory, without retaining a reference to it after construction. This 
will start a finalize-triggering chain per instance, with the chain "ticking" 
once per newgen cycle.

If you want to avoid having one of these (coming and going on each GC cycle) 
per CloseableMemory instance, you can use a common static detector and a 
registration mechanism (where each registered instance would have it's 
changeGuard() method call…

— Gil.


> On Jan 24, 2016, at 9:10 AM, Peter Levart  wrote:
> 
> Hi,
> 
> I had an idea recently on how to expedite the collection of an object. It is 
> simple - just don't let it live long.
> 
> Here's a concept prototype:
> 
> http://cr.openjdk.java.net/~plevart/misc/CloseableMemory/CloseableMemory.java
> 
> The overhead of the check in access methods (getByte()/setByte()) amounts to 
> one volatile read of an oop variable that changes once per say 5 to 10 
> seconds. That's the period a special guard object is alive. It's reachability 
> is tracked by the GC and extends to the end of each access method (using 
> Reference.reachabilityFence). Every few seconds, the guard object is changed 
> with new fresh one so that the chance of the guard and its tracking Cleaner 
> being promoted to old generation is very low.
> 
> Could something like that enable a low-overhead CloseableMappedByteBuffer?
> 
> Regards, Peter
> 
> On 01/23/2016 09:31 PM, Andrew Haley wrote:
>> On 23/01/16 20:01, Uwe Schindler wrote:
>> 
>>> It depends how small! If the speed is still somewhere between Java 8
>>> ByteBuffer performance and the recent Hotspot improvements in Java
>>> 9, I agree with trying it out. But some volatile memory access on
>>> every access is a no-go. The code around ByteBufferIndexInput in
>>> Lucene is the most performance-critical critical code, because on
>>> every search query or sorting there is all the work happening in
>>> there (millions of iterations with positional ByteBuffer.get*
>>> calls). As ByteBuffers are limited to 2 GiB, we also need lots of
>>> hairy code to work around that limitation!
>> Yes, I see that code.  It would be helpful if there were a
>> self-contained but realistic benchmark using that code.  That way,
>> some simple experiments would allow changes to be measured.
>> 
>>> If you look at ByteBufferIndexInput's code you will see that we
>>> simply do stuff like trying to read from one bytebuffer and only if
>>> we catch an BufferUnderflowException we fall back to handling buffer
>>> switches: Instead of checking bounds on every access, we have
>>> fallback code only happening on exceptions. E.g. if you are 3 bytes
>>> before end of one buffer slice and read a long, it will throw
>>> BufferUnderflow. When this happens the code will fall back to read
>>> byte by byte from 2 different buffers and reassemble the long):
>> I'm surprised you don't see painful deoptimization traps when that
>> happens.  I suppose it's rare enough that you don't care.  There's a
>> new group of methods in JDK9 called Objects.checkIndex() which are
>> intended to provide a very efficient way to do bounds checks. It might
>> be interesting to see if they work well with ByteBufferIndexInput:
>> that's an important use case.
>> 
>> BTW, does anyone here know why we don't have humongous ByteBuffers
>> with a long index?
>> 
>> Andrew.
> 



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-25 Thread Alan Bateman



On 25/01/2016 15:27, Peter Levart wrote:


But let me ask something. Doesn't GC processing require (at least in 
some phases) that user threads be stopped in a safepoint? What happens 
when a user thread is blocked by kernel on memory access? Such thread 
can't be stopped in a safepoint. Safepoint can't begin, so GC can't 
proceed and therefore can't promote objects to old generation at that 
time. Am I right? If yes, then time does not pass for objects while a 
user thread is blocked on memory access, so they won't get promoted to 
old gen any time sooner after the user thread is unblocked.
With memory mapping then it's very possible that a memory access to 
stall waiting for pages to be faulted in. So yes, I assume any 
STW/safepoint is going to be stall. On the other hand then threads doing 
file or socket I/O on these buffers will be in native (maybe blocked, 
maybe not) and so aren't an issue. They will safepoint on return or if 
they attempt to re-enter.


-Alan


Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-25 Thread Peter Levart



On 01/25/2016 02:31 PM, Alan Bateman wrote:

On 24/01/2016 17:10, Peter Levart wrote:

Hi,

I had an idea recently on how to expedite the collection of an 
object. It is simple - just don't let it live long.


Here's a concept prototype:

http://cr.openjdk.java.net/~plevart/misc/CloseableMemory/CloseableMemory.java 



The overhead of the check in access methods (getByte()/setByte()) 
amounts to one volatile read of an oop variable that changes once per 
say 5 to 10 seconds. That's the period a special guard object is 
alive. It's reachability is tracked by the GC and extends to the end 
of each access method (using Reference.reachabilityFence). Every few 
seconds, the guard object is changed with new fresh one so that the 
chance of the guard and its tracking Cleaner being promoted to old 
generation is very low.


Could something like that enable a low-overhead 
CloseableMappedByteBuffer?


If I read this correctly then this still depends on timely reference 
processing.


Right, the hope is that Reference(s) and referents that only live for a 
few seconds get this timely processing.


The switching guard trick to keep the Cleaner from being promoted is 
interesting of course. So if we were to do something like this with 
MBB then it would mean the file mapping would still exist and so we'd 
have the usual issue of trying to delete the underlying file. 


There could be a method on MBB to register a callback to be called after 
the buffer is unmapped.


Then we have the issue of file or socket I/O where threads could be 
blocked doing I/O with regions of the buffer and so delay indefinitely 
any release.


Yes, that could be a problem. If the access to mapped memory blocked for 
a very long time, then the guard and its Cleaner could be promoted to 
old gen in the meanwhile. But let me ask something. Doesn't GC 
processing require (at least in some phases) that user threads be 
stopped in a safepoint? What happens when a user thread is blocked by 
kernel on memory access? Such thread can't be stopped in a safepoint. 
Safepoint can't begin, so GC can't proceed and therefore can't promote 
objects to old generation at that time. Am I right? If yes, then time 
does not pass for objects while a user thread is blocked on memory 
access, so they won't get promoted to old gen any time sooner after the 
user thread is unblocked.


Regards, Peter



That said, maybe it is an option for Uwe.

-Alan.




Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-25 Thread Alan Bateman

On 24/01/2016 17:10, Peter Levart wrote:

Hi,

I had an idea recently on how to expedite the collection of an object. 
It is simple - just don't let it live long.


Here's a concept prototype:

http://cr.openjdk.java.net/~plevart/misc/CloseableMemory/CloseableMemory.java 



The overhead of the check in access methods (getByte()/setByte()) 
amounts to one volatile read of an oop variable that changes once per 
say 5 to 10 seconds. That's the period a special guard object is 
alive. It's reachability is tracked by the GC and extends to the end 
of each access method (using Reference.reachabilityFence). Every few 
seconds, the guard object is changed with new fresh one so that the 
chance of the guard and its tracking Cleaner being promoted to old 
generation is very low.


Could something like that enable a low-overhead 
CloseableMappedByteBuffer?


If I read this correctly then this still depends on timely reference 
processing. The switching guard trick to keep the Cleaner from being 
promoted is interesting of course. So if we were to do something like 
this with MBB then it would mean the file mapping would still exist and 
so we'd have the usual issue of trying to delete the underlying file. 
Then we have the issue of file or socket I/O where threads could be 
blocked doing I/O with regions of the buffer and so delay indefinitely 
any release.


That said, maybe it is an option for Uwe.

-Alan.


Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-24 Thread Peter Levart

Hi,

I had an idea recently on how to expedite the collection of an object. 
It is simple - just don't let it live long.


Here's a concept prototype:

http://cr.openjdk.java.net/~plevart/misc/CloseableMemory/CloseableMemory.java

The overhead of the check in access methods (getByte()/setByte()) 
amounts to one volatile read of an oop variable that changes once per 
say 5 to 10 seconds. That's the period a special guard object is alive. 
It's reachability is tracked by the GC and extends to the end of each 
access method (using Reference.reachabilityFence). Every few seconds, 
the guard object is changed with new fresh one so that the chance of the 
guard and its tracking Cleaner being promoted to old generation is very low.


Could something like that enable a low-overhead CloseableMappedByteBuffer?

Regards, Peter

On 01/23/2016 09:31 PM, Andrew Haley wrote:

On 23/01/16 20:01, Uwe Schindler wrote:


It depends how small! If the speed is still somewhere between Java 8
ByteBuffer performance and the recent Hotspot improvements in Java
9, I agree with trying it out. But some volatile memory access on
every access is a no-go. The code around ByteBufferIndexInput in
Lucene is the most performance-critical critical code, because on
every search query or sorting there is all the work happening in
there (millions of iterations with positional ByteBuffer.get*
calls). As ByteBuffers are limited to 2 GiB, we also need lots of
hairy code to work around that limitation!

Yes, I see that code.  It would be helpful if there were a
self-contained but realistic benchmark using that code.  That way,
some simple experiments would allow changes to be measured.


If you look at ByteBufferIndexInput's code you will see that we
simply do stuff like trying to read from one bytebuffer and only if
we catch an BufferUnderflowException we fall back to handling buffer
switches: Instead of checking bounds on every access, we have
fallback code only happening on exceptions. E.g. if you are 3 bytes
before end of one buffer slice and read a long, it will throw
BufferUnderflow. When this happens the code will fall back to read
byte by byte from 2 different buffers and reassemble the long):

I'm surprised you don't see painful deoptimization traps when that
happens.  I suppose it's rare enough that you don't care.  There's a
new group of methods in JDK9 called Objects.checkIndex() which are
intended to provide a very efficient way to do bounds checks. It might
be interesting to see if they work well with ByteBufferIndexInput:
that's an important use case.

BTW, does anyone here know why we don't have humongous ByteBuffers
with a long index?

Andrew.




RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-24 Thread Uwe Schindler
Hi all, hi Chris,

Thanks for the catch up! As we are continuously testing EA builds of OpenJDK 
with Apache Lucene, we will see the issues caused by this commit asap. So I 
would maybe delay our testing a bit, until the proposed changes of Alan are 
also committed and part of EA builds. Is there already an issue about that?

I opened an issue in the Apache Lucene tracker:
https://issues.apache.org/jira/browse/LUCENE-6989

I hope, we will find a good solution!

I had some other thoughts about the issue: Basically the forceful unmapping is 
only needed because the Grabage Collector never ever tries to finalize and GC 
the very small MappedByteBuffer instances, especially if they were living for 
longer time. But they are sitting on heavy resources, so maybe a solution to 
solve this would be:

- Add some special annotation in the JDK that is respected by all Garbage 
Collectors and makes them prefer those "heavy" instances. Something like 
@jdk.internal.Heavy
- Maybe add some close() method to MappedByteBuffer, but just make it a 
candidate for earlier Grabage Collection instead of doing risky unmapping. A 
solution may be to add it to some special GC queue or whatever. I have no idea 
if that’s possible, just tell GC: "I am done with this object, discard it asap 
if its unreachable!"

Uwe

-
Uwe Schindler
uschind...@apache.org 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/


> -Original Message-
> From: Chris Hegarty [mailto:chris.hega...@oracle.com]
> Sent: Saturday, January 23, 2016 11:52 PM
> To: Uwe Schindler 
> Cc: Alan Bateman ; core-libs-dev  d...@openjdk.java.net>
> Subject: Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
> 
> Just catching up…
> 
> I see no objection to the proposed patch, but the obvious concern ( that
> is highlighted in JEP 260 ), about the digging into the private internal
> details of NIO buffers.
> 
> I think Alan summarized the issues around providing a public API for
> releasing/unmapping native memory very well, and if this does not
> make it for JDK 9, then Alan’s alternative ( implements Runnable ) may
> be a better interim solution than the current use of reflection.
> 
> -Chris.
> 
> > On 23 Jan 2016, at 21:57, Uwe Schindler  wrote:
> >
> > Hi,
> >
> > Alan Bateman [mailto:alan.bate...@oracle.com] wrote:
> >> On 23/01/2016 19:23, Uwe Schindler wrote:
> >>> :
> >>>
> >>> What is the replacement for the following code (see marked
> BufferCleaner
> >> impl, which is our abstraction): https://goo.gl/DGYZZj
> >>>
> >>> The main reason why sun.misc.Cleaner was on the critical API list is NOT
> the
> >> case that somebody wanted to implement their own cleaner as
> replacement
> >> for finalization. The main reason (and this is *not* solved by the new APIs
> in
> >> java.lang.ref.Cleaner) is to *force* unmapping of direct and mmapped
> byte
> >> buffers.
> >> JEP 260 was updated recently to move this to an open issue and I think
> >> the text captures the issue correctly. Part of it that we can't have
> >> types in java.base depending on types in other modules and this is why
> >> Buffers can't have fields of type sun.misc.Cleaner or any type in sun.misc.
> >>
> >> As has come several times, there are huge security and reliability
> >> issues that arise when releasing or unmapping memory that is still
> >> accessible via reachable objects. Proposed solutions over the years have
> >> traded performance or were limited to platforms where we could
> >> atomically remap. JDK 9 may be the time to try yet again or else just
> >> introduce a JDK-specific API to unmap that comes with a warning in 96pt
> >> font. It might have to be disabled completely when running with a
> >> security manager. Alternatively the burden of the current hack could be
> >> reduced by having Cleaner implement Runnable with a run method that
> >> invokes clean. That would avoid needing to cast to a JDK-internal type
> >> and so avoiding needing to use -XaddExports to break encapsulation.
> >
> > We know this problem. Because of this, e.g. Elasticsearch runs with a
> security manager and only allows lucene-core.jar access to do this reflection
> on sun.misc package (using the correct permission, only given to JAR file).
> >
> > I was about to suggest the same thing: Maybe add a public API to byte
> buffer, that is documented to throw SecurityException. Add a new
> Runtime/WhateverPermission that can be enabled to work around that (e.g.,
> Elasticsearch would do this and allow this Permission only to 
> lucene-

Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Chris Hegarty
Just catching up…

I see no objection to the proposed patch, but the obvious concern ( that
is highlighted in JEP 260 ), about the digging into the private internal
details of NIO buffers.

I think Alan summarized the issues around providing a public API for 
releasing/unmapping native memory very well, and if this does not 
make it for JDK 9, then Alan’s alternative ( implements Runnable ) may
be a better interim solution than the current use of reflection.

-Chris.

> On 23 Jan 2016, at 21:57, Uwe Schindler  wrote:
> 
> Hi,
> 
> Alan Bateman [mailto:alan.bate...@oracle.com] wrote:
>> On 23/01/2016 19:23, Uwe Schindler wrote:
>>> :
>>> 
>>> What is the replacement for the following code (see marked BufferCleaner
>> impl, which is our abstraction): https://goo.gl/DGYZZj
>>> 
>>> The main reason why sun.misc.Cleaner was on the critical API list is NOT the
>> case that somebody wanted to implement their own cleaner as replacement
>> for finalization. The main reason (and this is *not* solved by the new APIs 
>> in
>> java.lang.ref.Cleaner) is to *force* unmapping of direct and mmapped byte
>> buffers.
>> JEP 260 was updated recently to move this to an open issue and I think
>> the text captures the issue correctly. Part of it that we can't have
>> types in java.base depending on types in other modules and this is why
>> Buffers can't have fields of type sun.misc.Cleaner or any type in sun.misc.
>> 
>> As has come several times, there are huge security and reliability
>> issues that arise when releasing or unmapping memory that is still
>> accessible via reachable objects. Proposed solutions over the years have
>> traded performance or were limited to platforms where we could
>> atomically remap. JDK 9 may be the time to try yet again or else just
>> introduce a JDK-specific API to unmap that comes with a warning in 96pt
>> font. It might have to be disabled completely when running with a
>> security manager. Alternatively the burden of the current hack could be
>> reduced by having Cleaner implement Runnable with a run method that
>> invokes clean. That would avoid needing to cast to a JDK-internal type
>> and so avoiding needing to use -XaddExports to break encapsulation.
> 
> We know this problem. Because of this, e.g. Elasticsearch runs with a 
> security manager and only allows lucene-core.jar access to do this reflection 
> on sun.misc package (using the correct permission, only given to JAR file).
> 
> I was about to suggest the same thing: Maybe add a public API to byte buffer, 
> that is documented to throw SecurityException. Add a new 
> Runtime/WhateverPermission that can be enabled to work around that (e.g., 
> Elasticsearch would do this and allow this Permission only to 
> lucene-core.jar). In addition add red and blinking warnings to this method :-)
> 
> In any case, a possible solution was proposed by Andrew Haley (he had some 
> ideas in the past, I think we brought this up the last time a few months ago) 
> with a small slowdown, but still providing better ByteBuffer performance than 
> in Java 7 or Java 8.
> 
> I would hope for a solution that installs a SIGSEGV signal handler in the 
> JDK, that translates any completely illegal access that would otherwise lead 
> to a crash of the JDK to some Java Exception. The security issues you also 
> mention do not apply for us (e.g., reading memory from another web 
> application in the same JVM), so a new permission for SecurityManager would 
> also help here.
> 
> Uwe
> 



RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Uwe Schindler
Hi Andrew,

Andrew Haley [mailto:a...@redhat.com] wrote:
> On 23/01/16 20:01, Uwe Schindler wrote:
> 
> > It depends how small! If the speed is still somewhere between Java 8
> > ByteBuffer performance and the recent Hotspot improvements in Java
> > 9, I agree with trying it out. But some volatile memory access on
> > every access is a no-go. The code around ByteBufferIndexInput in
> > Lucene is the most performance-critical critical code, because on
> > every search query or sorting there is all the work happening in
> > there (millions of iterations with positional ByteBuffer.get*
> > calls). As ByteBuffers are limited to 2 GiB, we also need lots of
> > hairy code to work around that limitation!
> 
> Yes, I see that code.  It would be helpful if there were a
> self-contained but realistic benchmark using that code.  That way,
> some simple experiments would allow changes to be measured.

Unfortunately I am a bit occupied with preparing for FOSDEM and also we 
switched Lucene/Solr to GIT today, so I cannot write a benchmark today. I know 
that Robert Muir (I CC'ed him) did a lot of performance testing with the 
ByteBufferIndexInput, maybe we can work both on some isolated benchmark, that 
you can use for testing. But this may take a while.

> > If you look at ByteBufferIndexInput's code you will see that we
> > simply do stuff like trying to read from one bytebuffer and only if
> > we catch an BufferUnderflowException we fall back to handling buffer
> > switches: Instead of checking bounds on every access, we have
> > fallback code only happening on exceptions. E.g. if you are 3 bytes
> > before end of one buffer slice and read a long, it will throw
> > BufferUnderflow. When this happens the code will fall back to read
> > byte by byte from 2 different buffers and reassemble the long):
> 
> I'm surprised you don't see painful deoptimization traps when that
> happens.  I suppose it's rare enough that you don't care.

Exactly! Of course the accesses to the ByteBufferIndexInput are not really 
completely random. You always have accesses concentrated on places close 
(otherwise this would produce lots of swapping and I/O). As the size of the 
ByteBuffer (the chunkSizePower in this code) is 1 GiB (2^30) by default, the 
probability to catch that exception and cause deoptimization is very low. By 
the way it is not 2 GiB, because signed integers and maximum array size in Java 
don't allow to reach 2^31 (only 2^21 - 1, damn!). So we chunk the file into 1 
GiB large ByteBuffers.

> There's a
> new group of methods in JDK9 called Objects.checkIndex() which are
> intended to provide a very efficient way to do bounds checks. It might
> be interesting to see if they work well with ByteBufferIndexInput:
> that's an important use case.

We can check for this. The main idea in this code is to not do similar bounds 
checks both in ByteBuffer and outside. After switching to the try/catch we 
improved the whole situation. We can try with Java 9, but using 
Objects.checkIndex() can at earliest be used once Lucene is on Java 9 (or with 
Multi-Version-JAR files with ByteBufferIndexInput alternate impl for Java 9+).

> BTW, does anyone here know why we don't have humongous ByteBuffers
> with a long index?

I think 64 bit arrays were proposed for Java 10, so are ByteBuffers with longs 
(or VarHandles using longs). This is also an old and long going discussion.

Uwe

> Andrew.

Thanks,
Uwe



RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Uwe Schindler
Hi,

Alan Bateman [mailto:alan.bate...@oracle.com] wrote:
> On 23/01/2016 19:23, Uwe Schindler wrote:
> > :
> >
> > What is the replacement for the following code (see marked BufferCleaner
> impl, which is our abstraction): https://goo.gl/DGYZZj
> >
> > The main reason why sun.misc.Cleaner was on the critical API list is NOT the
> case that somebody wanted to implement their own cleaner as replacement
> for finalization. The main reason (and this is *not* solved by the new APIs in
> java.lang.ref.Cleaner) is to *force* unmapping of direct and mmapped byte
> buffers.
> JEP 260 was updated recently to move this to an open issue and I think
> the text captures the issue correctly. Part of it that we can't have
> types in java.base depending on types in other modules and this is why
> Buffers can't have fields of type sun.misc.Cleaner or any type in sun.misc.
> 
> As has come several times, there are huge security and reliability
> issues that arise when releasing or unmapping memory that is still
> accessible via reachable objects. Proposed solutions over the years have
> traded performance or were limited to platforms where we could
> atomically remap. JDK 9 may be the time to try yet again or else just
> introduce a JDK-specific API to unmap that comes with a warning in 96pt
> font. It might have to be disabled completely when running with a
> security manager. Alternatively the burden of the current hack could be
> reduced by having Cleaner implement Runnable with a run method that
> invokes clean. That would avoid needing to cast to a JDK-internal type
> and so avoiding needing to use -XaddExports to break encapsulation.

We know this problem. Because of this, e.g. Elasticsearch runs with a security 
manager and only allows lucene-core.jar access to do this reflection on 
sun.misc package (using the correct permission, only given to JAR file).

I was about to suggest the same thing: Maybe add a public API to byte buffer, 
that is documented to throw SecurityException. Add a new 
Runtime/WhateverPermission that can be enabled to work around that (e.g., 
Elasticsearch would do this and allow this Permission only to lucene-core.jar). 
In addition add red and blinking warnings to this method :-)

In any case, a possible solution was proposed by Andrew Haley (he had some 
ideas in the past, I think we brought this up the last time a few months ago) 
with a small slowdown, but still providing better ByteBuffer performance than 
in Java 7 or Java 8.

I would hope for a solution that installs a SIGSEGV signal handler in the JDK, 
that translates any completely illegal access that would otherwise lead to a 
crash of the JDK to some Java Exception. The security issues you also mention 
do not apply for us (e.g., reading memory from another web application in the 
same JVM), so a new permission for SecurityManager would also help here.

Uwe



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Alan Bateman


On 23/01/2016 19:23, Uwe Schindler wrote:

:

What is the replacement for the following code (see marked BufferCleaner impl, 
which is our abstraction): https://goo.gl/DGYZZj

The main reason why sun.misc.Cleaner was on the critical API list is NOT the 
case that somebody wanted to implement their own cleaner as replacement for 
finalization. The main reason (and this is *not* solved by the new APIs in 
java.lang.ref.Cleaner) is to *force* unmapping of direct and mmapped byte 
buffers.
JEP 260 was updated recently to move this to an open issue and I think 
the text captures the issue correctly. Part of it that we can't have 
types in java.base depending on types in other modules and this is why 
Buffers can't have fields of type sun.misc.Cleaner or any type in sun.misc.


As has come several times, there are huge security and reliability 
issues that arise when releasing or unmapping memory that is still 
accessible via reachable objects. Proposed solutions over the years have 
traded performance or were limited to platforms where we could 
atomically remap. JDK 9 may be the time to try yet again or else just 
introduce a JDK-specific API to unmap that comes with a warning in 96pt 
font. It might have to be disabled completely when running with a 
security manager. Alternatively the burden of the current hack could be 
reduced by having Cleaner implement Runnable with a run method that 
invokes clean. That would avoid needing to cast to a JDK-internal type 
and so avoiding needing to use -XaddExports to break encapsulation.


-Alan.


Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Andrew Haley
On 23/01/16 20:01, Uwe Schindler wrote:

> It depends how small! If the speed is still somewhere between Java 8
> ByteBuffer performance and the recent Hotspot improvements in Java
> 9, I agree with trying it out. But some volatile memory access on
> every access is a no-go. The code around ByteBufferIndexInput in
> Lucene is the most performance-critical critical code, because on
> every search query or sorting there is all the work happening in
> there (millions of iterations with positional ByteBuffer.get*
> calls). As ByteBuffers are limited to 2 GiB, we also need lots of
> hairy code to work around that limitation!

Yes, I see that code.  It would be helpful if there were a
self-contained but realistic benchmark using that code.  That way,
some simple experiments would allow changes to be measured.

> If you look at ByteBufferIndexInput's code you will see that we
> simply do stuff like trying to read from one bytebuffer and only if
> we catch an BufferUnderflowException we fall back to handling buffer
> switches: Instead of checking bounds on every access, we have
> fallback code only happening on exceptions. E.g. if you are 3 bytes
> before end of one buffer slice and read a long, it will throw
> BufferUnderflow. When this happens the code will fall back to read
> byte by byte from 2 different buffers and reassemble the long):

I'm surprised you don't see painful deoptimization traps when that
happens.  I suppose it's rare enough that you don't care.  There's a
new group of methods in JDK9 called Objects.checkIndex() which are
intended to provide a very efficient way to do bounds checks. It might
be interesting to see if they work well with ByteBufferIndexInput:
that's an important use case.

BTW, does anyone here know why we don't have humongous ByteBuffers
with a long index?

Andrew.


RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Uwe Schindler
Hi,

> Here's a question for you: could you tolerate a closeable mapped
> ByteBuffer which was somewhat slower to access?  It is hard to make a
> secure closeable mapped ByteBuffer: the question is how small the
> overhead of closeability can be made.

Lucene uses the ByteBuffer like a conventional byte[] arrays and expects as 
close performance to that as possible. In Java 7 and Java 8 there is for sure 
some large overhead because of missing Hotspot optimizations. In Java 9 we 
found out, that recent builds are now almost as fast as byte[] access. 
Completely destroying that improvement would be no good. :-(

We are also looking into using VarHandles instead of ByteBuffers directly 
(using the new MethodHandles methods to get a VarHandle on top of any 
ByteBuffer, although this does not really fit our use-case completely, because 
we cannot use views like long[] on top of a ByteBuffer, because we sometimes 
also need unaligned accesses). We will try to check this out as soon as first 
builds with VarHandles are available. Of course this would also not help, if a 
Closeable ByteBuffer would also slowdown the VarHandle accesses.

> But if the answer is "We can't tolerate *any* additional overhead, no
> matter how small" then there is no motivation to do any experiments.

It depends how small! If the speed is still somewhere between Java 8 ByteBuffer 
performance and the recent Hotspot improvements in Java 9, I agree with trying 
it out. But some volatile memory access on every access is a no-go. The code 
around ByteBufferIndexInput in Lucene is the most performance-critical critical 
code, because on every search query or sorting there is all the work happening 
in there (millions of iterations with positional ByteBuffer.get* calls). As 
ByteBuffers are limited to 2 GiB, we also need lots of hairy code to work 
around that limitation!

If you look at ByteBufferIndexInput's code you will see that we simply do stuff 
like trying to read from one bytebuffer and only if we catch an 
BufferUnderflowException we fall back to handling buffer switches: Instead of 
checking bounds on every access, we have fallback code only happening on 
exceptions. E.g. if you are 3 bytes before end of one buffer slice and read a 
long, it will throw BufferUnderflow. When this happens the code will fall back 
to read byte by byte from 2 different buffers and reassemble the long): 
https://goo.gl/g1jKcm Stuff like sorting will make heavy use of the 
ByteBufferIndexInput's (RandomAccessIndexInput interface's) methods like 
readXxx(long position) for stuff like quicksort with really hundreds of 
millions of items!

> Andrew.

Thanks,
Uwe



Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Andrew Haley
Here's a question for you: could you tolerate a closeable mapped
ByteBuffer which was somewhat slower to access?  It is hard to make a
secure closeable mapped ByteBuffer: the question is how small the
overhead of closeability can be made.

But if the answer is "We can't tolerate *any* additional overhead, no
matter how small" then there is no motivation to do any experiments.

Andrew.


RE: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Uwe Schindler
(reposting with correct sender address)

Hi,

> Note: some popular open source libraries that hack into the internal
> private cleaner field of direct buffers will have to have their code
> updated, if they wish to continue to do this.

I followed parts of this issue, but as representative from Apache Lucene, which 
really really needs to un-mmap MappedByteBuffers (otherwise Lucene gets 
unuseable with JDK 9), I have no idea what the fix for us should be?

What is the replacement for the following code (see marked BufferCleaner impl, 
which is our abstraction): https://goo.gl/DGYZZj

The main reason why sun.misc.Cleaner was on the critical API list is NOT the 
case that somebody wanted to implement their own cleaner as replacement for 
finalization. The main reason (and this is *not* solved by the new APIs in 
java.lang.ref.Cleaner) is to *force* unmapping of direct and mmapped byte 
buffers.

The unmapping of mmapped buffers is really needed and must be in Java 9, 
otherwise projects like Lucene will not work with Java 9, or may be slow as 
hell (if they use non-mmapped I/O) or otherwise run out of disk space (because 
mmapped files use disk space as they are never ever freed by the GC - see 
below). On Windows, in addition, files that are mmapped cannot be closed. These 
problem are the worst desaster that can happen to Lucene - a desaster like the 
big Hotspot issues back in 2011.

With this patch the above code part would no longer work, because you can still 
make the getCleaner method available with setAccessible in Java 9 Jigsaw, but 
invoking the clean() method on the cleaner will horribly fail, because the 
cleaner is part of an internal package.

So you have 2 possibilities:
- Re-add sun.misc.Cleaner with a limited API (only the public clean() method) 
and let DirectBuffer return an instance of this sun.misc.Cleaner public API, so 
it is accessible without breaking encapsulation by adding extra exports
- Or fix the full issue: Add "official" support to unmmap mmapped files. 
Really! You have to do this, otherwise it's a desaster (see below for the 
"why").

Mark Reinhold: I will as every year contact you on the FOSDEM dinner about 
sun.misc.Cleaner and unmapping DirectBuffers :-) Be sure to have a heated 
discussion!

FYI: The reason why unmapping mmapped buffers is really needed is the 
following: MappedByteBuffer/DirectBuffers are very small objects (GC wise). 
Those are created by Lucene on mapping huuge files (several tens or 
hundreds of Gigabytes for some large indexes). Those objects live for longer 
time (up to several hours). But from time to time, Lucene releases the buffers 
and maps new ones (when updates occur on disk). Because those small - only a 
few bytes for the Garbage Collector - buffer instances lived so long, there is 
no reason to free them asap by GC. In fact, they are never freed if your 
application runs for several days (as Lucene/SOlr/Elasticsearch servers are 
living). So the small 20 byte objects hang forever on gigabytes of data! No way 
to realease that!

So Lucene/Solr/Elasticserach's misuse of sun.misc.Cleaner is just to force the 
DirectBuffers to free the huge amounts of resources they hold. The new API of 
java.lang.ref.Cleaner does not help at all with this. You are just hiding the 
only possible workaround!

Sorry for the bad news, but there needs to be a decision! We are great 
supporters of Jigsaw, but if we have to disable Jigsaw encapsulation, just to 
get access to jdk.internal.**.Cleaner, you are destroying the additional 
encapsulation for us!

Please add a new issue to either revert to have sun.misc.Cleaner available just 
to forcefully free mmapped files, or add an official API to allow unmapping 
(including Hotspot changes to prevent SIGSEGV/SIGBUS).

Uwe

-
Uwe Schindler
uschind...@apache.org 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/

> -Original Message-
> From: core-libs-dev [mailto:core-libs-dev-boun...@openjdk.java.net] On
> Behalf Of Chris Hegarty
> Sent: Saturday, January 23, 2016 5:17 PM
> To: core-libs-dev 
> Subject: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref
> 
> sun.misc.Cleaner was previously listed as a critical internal API in JEP
> 260 [1], but on further investigation it has been moved to an open issue,
> for the following reasons:
>   1) its primary use in the JDK is within NIO direct buffers to release
>  native memory. The base module cannot have a dependency on the
>  jdk.unsupported module so will need to be updated to use an
>  alternative cleaner,
>   2) the usage of Cleaner outside the JDK, as determined by corpus
>  analysis, has largely been observed to hack into private fields of
>  the internal NIO direct buffer classes to explicitly release native
>  memory.
> 
> As stated in 1), the type of the cleaner used by NIO dir

Re: RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Alan Bateman



On 23/01/2016 16:16, Chris Hegarty wrote:

:

Webrev:
   http://cr.openjdk.java.net/~chegar/8148117/


This has to move to your patch looks okay. You might need to update the 
TEST.groups to ensure that the existOnThrow tests will be run by jdk_core.


-Alan.


RFR [9] 8148117: Move sun.misc.Cleaner to jdk.internal.ref

2016-01-23 Thread Chris Hegarty
sun.misc.Cleaner was previously listed as a critical internal API in JEP
260 [1], but on further investigation it has been moved to an open issue,
for the following reasons:
  1) its primary use in the JDK is within NIO direct buffers to release
 native memory. The base module cannot have a dependency on the
 jdk.unsupported module so will need to be updated to use an
 alternative cleaner,
  2) the usage of Cleaner outside the JDK, as determined by corpus
 analysis, has largely been observed to hack into private fields of
 the internal NIO direct buffer classes to explicitly release native
 memory.

As stated in 1), the type of the cleaner used by NIO direct buffers will
have to change. Given this, and the fact that JDK 9 has a new general
purposed cleaner API, java.lang.ref.Cleaner [2] the value of keep
sun.misc.Cleaner is questionable.

This issue proposes to simply move Cleaner into an internal non-exported
package in the base module so that it can be used by the NIO direct
buffers classes, and small number of other places.

Webrev:
  http://cr.openjdk.java.net/~chegar/8148117/


If, at some point in the future, it is determined that sun.misc.Cleaner
is in fact a critical internal API ( with static usage ), then it can be
reinstated as a subtype of jdk.internal.ref.Cleaner, providing the same
public API.

Note: some popular open source libraries that hack into the internal
private cleaner field of direct buffers will have to have their code
updated, if they wish to continue to do this.

-Chris.

[1] https://bugs.openjdk.java.net/browse/JDK-8132928
[1] https://bugs.openjdk.java.net/browse/JDK-8138696