On Thu, 14 May 2026 16:10:11 GMT, Alexander Zuev <[email protected]> wrote:

>> That is a great question, and it's the heart of what I don't understand well 
>> here. (It's also why my original draft (which was much more invasive) moved 
>> a lot more logic into the `dispose` method.)
>> 
>> Further testing/exploration led me to believe the CAccessible object is 
>> never intended to be discarded. It is created once and permanently linked to 
>> its analog AccessibleContext in `getCAccessible`. (This is the only place 
>> where `setNativeAXResource` is ever called in the codebase; it is _never_ 
>> nullified to release the CAccessible for GC.)
>> 
>>> under normal circumstances component has only one CAccessible but that can 
>>> change and in this case wouldn't it be a potential memory leak
>> 
>> Is this a hypothetical, or is there a specific usage pattern you're thinking 
>> of (that I'd like to learn about)?
>> 
>> What event could lead us to uninstall this new "ancestor" PCL? I can't think 
>> of a universal signal that tells us "we're ready to uninstall now", given 
>> what I (think I) understand about how CAccessible's work.
>> 
>> ## Alternative Proposal
>> 
>> How about this alternative (borrowed from 
>> [here](https://github.com/mickleness/swing-accessibility/blob/main/src/main/java/com/pump/ax/mac/MacFixChangingAncestor.java)):
>> 
>> We never add a PCL to any Component. Instead we listen to _all_ 
>> COMPONENT_REMOVED events:
>> 
>> 
>> static {
>>     AWTEventListener componentRemovedListener = new AWTEventListener() {
>>         @Override
>>         public void eventDispatched(AWTEvent event) {
>>             if (event.getID() == ContainerEvent.COMPONENT_REMOVED) {
>>                 ContainerEvent containerEvent = (ContainerEvent) event;
>>                 CAccessible ca = 
>> getCAccessibleOnlyIfOneAlreadyExists(containerEvent.getChild());
>>                 if (ca != null)
>>                     ca.dispose();
>>             }
>>         }
>>     };
>>     
>> Toolkit.getDefaultToolkit().addAWTEventListener(componentRemovedListener, 
>> ContainerEvent.CONTAINER_EVENT_MASK);
>> }
>> 
>> 
>> Would this bypass concerns about memory leaks?
>
> There is no "uninstalling" of the accessible peer since there is no event 
> that tells us that we are no longer in use by the accessibility system, i am 
> mostly concerned for some code path that creates and replaces the accessible 
> peer with the new one - the old one will be referenced by the PCL. That is 
> more of the theoretical question - but i think i like the global listener 
> approach more.

OK, this is updated to use the global/static listener.

This approach won't call CAccessible.dispose() for a java.awt.Window's 
CAccessible object, but I think that's fine. (Unless someday we come up with 
different steps/bugs that benefit from addressing Windows also.)

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/30578#discussion_r3244254902

Reply via email to