JNI - question about jmethodid values.
coleen.phillimore at oracle.com
coleen.phillimore at oracle.com
Tue Nov 27 23:52:12 UTC 2018
Hi I have a couple of comments.
On 11/26/18 2:33 PM, Thomas Stüfe wrote:
> Hey JC,
> On Mon, Nov 26, 2018 at 8:15 PM JC Beyler <jcbeyler at google.com> wrote:
>> Hi all,
>> Just added my two cents on one comment:
>> On Mon, Nov 26, 2018 at 5:00 AM Thomas Stüfe <thomas.stuefe at gmail.com> wrote:
>>> Hi Peter,
>>> On Mon, Nov 26, 2018 at 1:02 PM Peter Hull <peterhull90 at gmail.com> wrote:
>>>> Hi Thomas,
>>>> Thank you very much for the detailed explanation. For your
>>>> information, the relevant NetBeans bug is
>>>> On Sat, Nov 24, 2018 at 3:41 PM Thomas Stüfe <thomas.stuefe at gmail.com> wrote:
>>>>> A jmethodid is a pointer to malloc'ed memory.
>>>> OK. Just in case I haven't understood it - does this mean a jmethodid,
>>>> once 'created', won't change (after garbage collection or whatever)?
>>> yes. It lives on, unchanged, forever. Even if the associated class is
>>> unloaded. That must be since outside JNI/JVMTI code may call in with
>>> outdated jmethodids which we must be able to handle gracefully.
>> This is the current design and most likely will remain for quite a bit but it is not defined by the SPEC to be like this so, in essence, it is an implementation detail that could be not true in future releases ;-)
> I politely disagree :)
> JNI spec says that you have a function like this:
> jmethodID GetMethodID(..)
> returning a jmethodid which you can then use in subsequent JNI
> functions. These functions are required to behave in a predictable way
> if the jmethodid has gotten invalid. The spec has no way to inform the
> caller if a jmethodid has gotten invalid by class unloading. Since the
> jmethodid is handed up to the caller and stored by him, there is no
> way to change its value on the fly either.
> So even though the spec does not specifically say that jmethodid lives
> forever, it is laid out in a way that prevents jmethodids from ever
> becoming invalid, and from changing their numerical value. This can of
> course change, but not without changing the JNI spec.
> I think my point is that Peter can rely on this behavior without fear
> that it will change in the future without him noticing. Before this
> behavior changes, the JNI spec would have to change.
> Cheers, Thomas
If the class is unloaded, the jmethodID is cleared. Native code should
first test whether it's NULL. I think that is the predictable behavior
that the spec requires.
Also, the jmethodIDs were never in the PermGen but in CHeap allocated
memory blocks. The Method* that was in the jmethodID was in the
permgen. I don't think there was any guarantee of contiguity (is that a
word) but they are allocated together in a block. After permgen was
removed, the blocks were sorted by class loader, so that the class
loader data could point to them for clearing.
>>>>> But it is not guaranteed to work. I would probably rather use a
>>>>> hashmap or similar.
>>>> I need to look at the implications on more detail but think it would
>>>> make sense to use long/jlong instead of int/jint on all platforms; the
>>>> extra memory use shouldn't be a problem. I think the IDs are just
>>>> stored on the Java side and used to get the method name and signature
>>>> later. That should be a loss-free cast, shouldn't it?
>>>>> If this is
>>>>> true, this 4x30bit assumption may actually have worked before jdk8,
>>>>> since the java heap is allocated as one continuous space, with the
>>>>> PermGen clustered in one part of it.
>>>> Indeed we did only start to get crashes on JDK9 and later (only
>>>> observed on Windows, macOS seems OK and other platforms have not been
>>>> Yours sincerely,
>>> Cheers, Thomas
More information about the discuss