DirectBuffer deallocation

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

DirectBuffer deallocation

elect
I need definitely to find a way to deallocate this damn direct buffers

I tried with

((DirectBuffer) directBuffer).cleaner().clean();

But I get a null exception, if I expand the function

try {
            //        ((DirectBuffer) directBuffer).cleaner().clean();
            if(!directBuffer.isDirect()) {
                return;
            }
           
            Method cleanerMethod = directBuffer.getClass().getMethod("cleaner");
            cleanerMethod.setAccessible(true);
            Object cleaner = cleanerMethod.invoke(directBuffer);
            Method cleanMethod = cleaner.getClass().getMethod("clean");
            cleanMethod.setAccessible(true);
            cleanMethod.invoke(cleaner);
           
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException
                | IllegalArgumentException | InvocationTargetException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }

I receive a null at this line:

            Method cleanMethod = cleaner.getClass().getMethod("clean");

Why?

@Julien your class  can easily be modified to accept also direct short/int/float buffers?
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
Hi

My class already supports short, int, float, char, long, ... direct buffers. Maybe you have found a bug. Keep in mind that my class is under GPL v2 which is a viral license.

The cleaner is often null, when it is no longer needed because the native resource has been released or in tons of cases, it's specific to each implementation, for example when using views on a direct byte buffer (asFloatBuffer(), ...).
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
In reply to this post by elect
Use getDeclaredMethod instead of getMethod because the latter only works on the public member methods as it is explained in the Java documentation:
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getMethod(java.lang.String,%20java.lang.Class...)
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
In reply to this post by elect
If you need another source of inspiration, look at com.jme3.util.BufferUtils.destroyDirectBuffer() but it's a lot less robust and less portable than my deallocator :)
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

elect
In reply to this post by gouessej
gouessej wrote
Use getDeclaredMethod instead of getMethod
I changed both getMethod to getDeclaredMethod but nothing changed unfortunately

protected void deallocateDirectShortBuffer(ShortBuffer directBuffer) {
//        ((DirectBuffer) directBuffer).cleaner().clean();
        try {
            if (!directBuffer.isDirect()) {
                return;
            }
            Method cleanerMethod = directBuffer.getClass().getDeclaredMethod("cleaner");
            cleanerMethod.setAccessible(true);
            Object cleaner = cleanerMethod.invoke(directBuffer);
            Method cleanMethod = cleaner.getClass().getDeclaredMethod("clean");
            cleanMethod.setAccessible(true);
            cleanMethod.invoke(cleaner);

        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
    }



gouessej wrote
The cleaner is often null, when it is no longer needed because the native resource has been released or in tons of cases, it's specific to each implementation, for example when using views on a direct byte buffer (asFloatBuffer(), ...).
I still get a null there, I tried to deallocate the direct buffer even before using it and it still returns null... but it cannot be already deallocated at that time since my sample works and relies on that data..



gouessej wrote
If you need another source of inspiration, look at com.jme3.util.BufferUtils.destroyDirectBuffer() but it's a lot less robust and less portable than my deallocator :)
Could you explain briefly why?

gouessej wrote
Hi

My class already supports short, int, float, char, long, ... direct buffers. Maybe you have found a bug. Keep in mind that my class is under GPL v2 which is a viral license.
Nice. What means gpl v2 practically? May I use in my projects?

If yes, how does it work? I just instantiate the DeallocationHelper and call DeallocationHelper.deallocate(directBuffer)?
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

jmaasing
elect wrote
Nice. What means gpl v2 practically? May I use in my projects?
It means that if you use the source or a JAR-file (yes even the binary according to EFF) you must provide the source code for _your_ application to your users and you _must_ use a GPLv2 license-compatible, that is the viral part.
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

elect
This post was updated on .
jmaasing wrote
It means that if you use the source or a JAR-file (yes even the binary according to EFF) you must provide the source code for _your_ application to your users and you _must_ use a GPLv2 license-compatible, that is the viral part.
Thanks for the clarification, jmaasing ;)

Pity then, since I am using mit, I am gonna stick with the jm3 method

Edit: the jm3 method works flawless, why don't we include in GLBuffers?
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
Hi

The JME 3 method is a lot more limited than my deallocation helper, it only treats some easy cases and it supports only Oracle Java, OpenJDK and Android DVM / ART. I suggested you to look at its source code as its license is more permissive than the one I use. This kind of code is difficult to maintain, it can break and it can even cause JVM crashes, it shouldn't be put into GLBuffers.

I don't want to start a debate about licenses but if I explain in details what I spent several months to study, I'll allow you to "privatize" this knowledge whereas the use of the GPL is intended to prevent that. I contribute to numerous projects with various licenses even though I have a strong preference for the GPL and I'd be glad not to be criticized by the developers who prefer more permissive licenses. Using the GPL isn't a pity, it's my choice, I respect yours and I'm open minded enough to give you some other sources of inspiration even though I have never seen a "better" deallocation helper than mine.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

elect
gouessej wrote
Hi

The JME 3 method is a lot more limited than my deallocation helper, it only treats some easy cases and it supports only Oracle Java, OpenJDK and Android DVM / ART. I suggested you to look at its source code as its license is more permissive than the one I use. This kind of code is difficult to maintain, it can break and it can even cause JVM crashes, it shouldn't be put into GLBuffers.
Yep, I got it, but for my case right now is sufficient.

gouessej wrote
I don't want to start a debate about licenses but if I explain in details what I spent several months to study, I'll allow you to "privatize" this knowledge whereas the use of the GPL is intended to prevent that. I contribute to numerous projects with various licenses even though I have a strong preference for the GPL and I'd be glad not to be criticized by the developers who prefer more permissive licenses. Using the GPL isn't a pity, it's my choice, I respect yours and I'm open minded enough to give you some other sources of inspiration even though I have never seen a "better" deallocation helper than mine.
Julien, I don't know how you could intend that, but it wasn't a critic at all ;)

I remember I read once about a specific license type that basically allows you to use code also for commercial usage, but if you modify it, you have to release it, do you have a clou what this could be?
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
elect wrote
Yep, I got it, but for my case right now is sufficient.
Therefore, you should have written that it works flawlessly for your case, it's an important piece of information. However, I advise you to debug the source code the method in JMonkeyEngine 3, it doesn't throw a NullPointerException but I'm not sure that it really disposes the native resources even for your case. The last time I looked at its code, half of the viewed buffers (returned by ByteBuffer.as*Buffer()) weren't treated correctly. I advise you to spend some time in reading the source code of OpenJDK involved in the management of direct buffers.

elect wrote
Julien, I don't know how you could intend that, but it wasn't a critic at all ;)

I remember I read once about a specific license type that basically allows you to use code also for commercial usage, but if you modify it, you have to release it, do you have a clou what this could be?
The GPL doesn't prevent you from using my source code "for commercial usage", it forces the developers to use the GPL in their own source code. You probably talk about the LGPL, it constraints the property of the GPL in the library itself. Personally, I prefer using the GPL because I consider that proprietary source code shouldn't even exist but it's another debate.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
In reply to this post by elect
elect, the method used in JMonkeyEngine doesn't work with Java 1.9, it doesn't work if the private fields are renamed, it uses a very rudimentary "search" of the deallocatable buffer. There are about thirty different kinds of direct buffers if you take into account the access rights too (read only and read & write), only about one fourth of them is correctly treated by JMonkeyEngine whereas my deallocator treats them all.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

elect
Is gpl v2 compatible with lgpl? That is if I switch to that may I use your deallocator?
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
As long as I use the GPL version 2 (without classpath exception unlike OpenJDK), you can't use my deallocator without using the same license (or a more recent version of the GPL but not the LGPL), that's exactly why I chose this license. By the way, if you have a doubt concerning my code, run the unit test TestDeallocationHelper.

Don't use sun.nio.ch.DirectBuffer if you want to make your code work with Java 1.9 and later without using an hidden switch but it will drive your code less smart and more complicated.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

elect
This

private PointerBuffer indices = PointerBuffer.allocateDirect(2).put(0).put(0).rewind();


is always a direct buffer, isn't?
Reply | Threaded
Open this post in threaded view
|

Re: DirectBuffer deallocation

gouessej
Administrator
It's always a direct NIO buffer, it's written in the Java documentation of the method:
http://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/com/jogamp/common/nio/PointerBuffer.html#allocateDirect(int)
Julien Gouesse | Personal blog | Website