Foreign memory access with classes
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Nov 8 13:17:16 UTC 2022
Of course using native segments still incurs into some (hopefully
negligible) GC cost for maintaining these memory segment instances.
Different applications might have different requirements re. how much GC
allocation is considered "acceptable". In principle you can create a
single big memory segment for each "page" and just peek and poke at
memory through it, never materializing a single instance. If you do
that, GC overhead will be fairly low (if any).
On the other side of the spectrum you might have applications which
desire to materialize a memory segment memory into an immutable Java
object - perhaps to expose it with saner API to the outside world. In
this case the GC will have of course to do more work. Maybe escape
analysis will help a little if these allocations are short-lived and/or
used in a structured way. Valhalla will surely help in this regard,
since you can declare a value record:
```
value record Point(int x, int y) { ... }
```
Which you can construct from a segment (maybe a big shared segment that
contains other 1024 points). Thanks to Valhalla, allocation of this
Point object is cheap, and GC overhead might still be small.
I believe having immutable views such as the one above is superior to
having instances wrapping a memory segment. Although, in practice, you
can still wrap the share memory segment (the one with 1024 points) and
store maybe an offset to the start of the slice.
Also, once we have Valhalla, I believe MemorySegment will try to take
advantage of it. So MemorySegment could be a sealed interface whose all
implementations are de facto "primitive". With enough VM magic, this
might further reduce the cost associated with allocating lots and lots
of memory segment slices.
Maurizio
On 08/11/2022 12:32, Johannes Lichtenberger wrote:
> Stupid question, but what's suggested is something like
>
> `class Record(MemorySegment segment) {}`
>
> and read from the MemorySegment or write to it, right?
>
> Would it make sense for a database project to eliminate GC work due to
> high allocation counts of objects, e.g., in an in-memory buffer? In my
> case in SirixDB, we currently have 1024 records per page at most, and
> a single writer per resource accumulates these pages in a simple map
> only visible to this transaction. Regarding GC, these potentially long
> accumulations, until the in-memory cache is made durable, have high
> costs (thus, it's better to, for instance, to sync after every
> 500_000th record instead of 5_000_000th record, even if we have enough
> memory. However, there's a tradeoff as syncing to disk after more data
> has been accumulated in a long-running auto-commit trx is better for
> parallel serialization of the pages into buffers.
>
> With the off-heap memory due to the MemorySegment the instances are
> still created and the GC would have to mark the objects, or am I
> missing something? Maybe with value classes created on the stack it
> makes the big difference? :-)
>
> Kind regards
> Johannes
>
>
>
> Am Di., 8. Nov. 2022 um 11:44 Uhr schrieb Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com>:
>
> I believe adding Java syntax to model objects backed by memory
> segments
> might be pushing things a little too far. From a pedagogical
> perspective
> you would now have to explain to _every_ Java developers that
> there are
> two different kinds of objects, plain and native, and the rules which
> govern their access would be different (plain objects are
> garbage-collected, native objects are not).
>
> Seems like a nightmare, for a relatively little pay off. Note
> that, if
> you declare a record class with components X and Y, it is relatively
> easy to construct a function that can read a segment, with given
> struct
> layout into a record with matching components. I believe JPassport
> [1]
> does something in this direction. With something like this you get
> basically 90% of what you are aiming for, without the need to
> change the
> language by adding a new keyword, and making the programming model
> more
> complex for all the developers out there, including those who do not
> care about off-heap access.
>
> Cheers
> Maurizio
>
> [1] - https://github.com/boulder-on/JPassport/
> <https://urldefense.com/v3/__https://github.com/boulder-on/JPassport/__;!!ACWV5N9M2RV99hQ!LjgyPEt1F69CBaEFf3KrF_sXMKLPtPvLSlTMxTTJ3ylEyKgPBUZl-PerIyVO_laZvfihmfvXU3Pdms5COZ79evl8Czl_iUXQ2g$>
>
>
> On 08/11/2022 06:52, Red IO wrote:
> > I just had a crazy idea on how to make foreign memory access
> work and
> > feel like java native class member access.
> > The idea is that you define special classes maybe with an
> interface or
> > a special class keyword. This class can then be "constructed"
> using a
> > MemorySegment being bound by its special and temporal bounds. The
> > object would be either null or every memory access throws an
> exception
> > when the bounds are breached. The class would be implicitly
> final and
> > would extend a class Native.
> > This could look something like this :
> >
> > //c struct
> > typedef struct {
> > int x;
> > int y;
> > } Point;
> >
> > //java native class
> > public native class Point {
> >
> > int x;
> > int y;
> >
> > //implicit and forced private constructor
> > //normal creation would make things difficult
> > }
> >
> > MemorySegment data =... //native memory
> > Point p = data.object(Point.class);
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20221108/0fbd3998/attachment-0001.htm>
More information about the panama-dev
mailing list