[External] : Re: Experiment: Node properties

John Hendrikx john.hendrikx at gmail.com
Tue Feb 24 07:05:23 UTC 2026


Thanks for the taking the time to respond.

On 24/02/2026 00:32, Andy Goryachev wrote:
>
> > What trade off are you making here?  It seems we're trading a small
> memory gain for more CPU use (extra indirection, walking a list
> linearly to find the correct property on each use/access VS no
> indirection, no list walking).
>
>
> You are right.  The tradeoff is non-zero memory gain (a few megabytes,
> to the tune of maybe 5% of total heap size) at the cost of extra CPU
> cycles.  The rationale is that even though we consume extra CPU, it's
> much less noticeable because of the cache-friendly implementation and
> non-zero positive impact on garbage collector (less memory to scan).

What is more cache friendly about adding several extra indirections to
get to a property's value?  Let me see:

Before:

- isFocusTraversable(): get property -> get value

After:

- isFocusTraversable(): get fast map -> get key ArrayList -> get
internal array -> get value ArrayList -> get internal array -> get
property -> get value

For the garbage collector, the properties are likely going to be in an
area of the GC collector that will be scanned rarely, and not part of
the frequent scans for young objects. I don't think we can generally
conclude that having less memory used will have an overall positive
impact on the GC here.  The properties will be seen as long-lived by the
GC, and will reside in an area only scanned rarely, which has very
little impact on the performance of most GC implementations.  

>
>
> > Are the resource constrained platforms you named generally memory or
> CPU constrained?
>
>
> I asked Gluon for some feedback on iOS/Android.  However, my previous
> experience with a large trading application says that memory footprint
> savings outweighs the CPU cycles, so I would imagine we'll get a net
> gain even on the desktop.

That's anecdotal, and will depend on the type of application, platform,
CPU cores available, etc.  So while you may be correct for your trading
application, it may be completely the opposite for a task tracking
application. In general, memory use is hardly a factor for most
applications; most Java apps don't even bother to limit the heap, yet
complain about several GB's of memory use when they have a retained size
of less than half a GB.  Not that I'm not in favor of reducing memory
footprint, but I seriously wonder if there is much to gain at the
property level.


>
>
> > Have you investigated a breakdown of JavaFX memory use, and did the
> amount of memory used by properties come out on top here?
>
>
> There is some statistics provided in
> https://github.com/andy-goryachev-oracle/Test/blob/main/doc/Experiments/NodeProperties.md ,
> please take a look.
I took a look, but could only find statistics about properties. I didn't
see a breakdown of general JavaFX memory use (the other 95%) to see if
properties are the lowest hanging fruit.
>
>
> > Would the gains you made here become irrelevant or less relevant with
> Compact Object Headers [https://openjdk.org/jeps/519]
>
>
> Compact Object Headers are almost irrelevant here - the stats that
> were collected count the number of pointers saved (assumed 8 bytes per
> pointer on 64 bit).  The stats ignore any other possible savings.

Compact Object Headers is especially relevant here as you're optimizing
small objects (properties) on which JEP519 offers the most relative
gain.  Enabling it may reduce the 5% memory gain you measured to a
smaller margin, which impacts the rationale for this change.

Furthermore, if we're talking about saving memory, I think we can assume
we're using small heaps (less than 32 GB).  In that case, Hotspot will
use 4 bytes per pointer (compressed OOPs) not 8, so your assumption of 8
bytes per pointer will be incorrect in the vast majority of JavaFX cases.

>
>
> > I think the property look-up system cannot reasonably be List
> (FastMap despite its name is a List). Converting this to a map however
> is likely to require a small object (like Map.Entry) which will
> further reduce any gains you made here I think.
>
>
> The FastMap is a map-like (key-value) storage, even though it's
> implemented as an array.  There is a debate as to what would the most
> efficient implementation entail (a hashmap, one array, or two arrays
> like the POC currently uses).  The idea is not to put *all*​ the
> properties into the container, but only the rarely used ones, with the
> end result of having a few (less than 4-6, say).  This makes the
> object small and cache-friendly, which further speeds up the access.

I'm aware of the intentions to only put the rarely used properties
there.  What is rarely used will depend on the application.  How many
properties will end up being stored there also depends on the
application.  What if the app does need several of these properties and
this structure grows to contain 20-30 properties?

Currently your proposal wants to store these rarely used properties in
an O(n) structure, whereas a hash based solutions are O(1), and where
doing nothing is even faster as there is no map at all.

So although your map implementation may be small and cache friendly
(that last point being debatable, see indirection count), it degrades
badly when there are more than the predicted amount of properties, and
requires many more indirections than the base case of doing nothing.

There is talk about not having to do an expensive `hashCode` call in
your proposal.  First, `hashCode` is really cheap for objects not
implementing equality as it falls back on the Object#hashCode.  I
believe this is the case for properties.  Even if it isn't the case, you
could use the identity hash code here (the `==` equivalent in the
hashing world).

However that "expensive" call is what enables the O(1) lookup of the
value you are interested in, which can be truly cache friendly with the
right structure (array based open addressed map).

--John

>
>
> Thanks!
>
> -andy
>
>
>
>
> *From: *openjfx-dev <openjfx-dev-retn at openjdk.org> on behalf of John
> Hendrikx <john.hendrikx at gmail.com>
> *Date: *Thursday, February 19, 2026 at 15:28
> *To: *openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
> *Subject: *Re: Experiment: Node properties
>
>
> On 04/02/2026 22:17, Andy Goryachev wrote:
>
>     I would like to share the results of a little experiment involving
>     optimization of storage of Node properties.  The basic idea is to
>     create a compact fast map-like container to hold the rarely
>     instantiated properties in order to reduce the application memory
>     footprint.
>
>     The savings are not overwhelming, but not exactly zero.  I would
>     imagine this optimization might be more interesting in any
>     resource constrained environment such as Android / iOS /
>     RaspberryPi.  Please refer to [0] for the details.
>
> What trade off are you making here?  It seems we're trading a small
> memory gain for more CPU use (extra indirection, walking a list
> linearly to find the correct property on each use/access VS no
> indirection, no list walking).
>
> Are the resource constrained platforms you named generally memory or
> CPU constrained?
>
> Have you investigated a breakdown of JavaFX memory use, and did the
> amount of memory used by properties come out on top here?
>
> Would the gains you made here become irrelevant or less relevant with
> Compact Object Headers [https://openjdk.org/jeps/519]
>
>
>
>     I encourage you to try it with your application, to see whether
>     you notice any change in memory consumption and/or performance.
>      Let me know what you think!
>
> I like the idea, but I wonder if there really is much to gain here,
> and whether those gains will hold up with future Java improvements.
>
> I think the property look-up system cannot reasonably be List (FastMap
> despite its name is a List). Converting this to a map however is
> likely to require a small object (like Map.Entry) which will further
> reduce any gains you made here I think.
>
> --John
>
>
>     Cheers,
>     -andy
>
>
>     *References*
>
>     [0]
>     https://github.com/andy-goryachev-oracle/Test/blob/main/doc/Experiments/NodeProperties.md
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20260224/0ebe1ef3/attachment-0001.htm>


More information about the openjfx-dev mailing list