MappedMemorySegment & in-memory filesystems

Ty Young youngty1997 at gmail.com
Wed Jun 24 06:57:40 UTC 2020


On 6/22/20 9:11 AM, Ty Young wrote:
>
>
>>
>> In other words, I think you should really go down the mapped segment 
>> path if you care about persistence - if that's not your primary use 
>> case, I think that's probably not the right tool for the job?
>
>
> There is no other option - realloc, as you've said before, makes zero 
> commitments in regards to whether the address you get back is purely 
> just expanded. If I went down that path, I'd have to create a messy 
> way to rebase all existing instances of MemoryAddress on the new 
> memory chunk.
>
>
> With MappedMemorySegment this is not the case as it's based on the 
> same file. All existing instances of MemoryAddress are valid since 
> they are backed by the file.
>
>

If the answer is no then whatever. There are in-memory filesystems 
available for Java, they just aren't apart of the JDK nor do they use 
JPMS. Given that a large part of FMA deals with memory I thought it was 
related.


Anyway, the fact that this works is kinda suspect. I wasn't able to 
determine whether or not this is already known about internally after 
gazing into my magical mind-reading crystal ball, so apologies I guess.


TL;DR, by using MemorySegment.ofNativeRestricted you can create a 
MemorySegment that is in a limbo state. This segment will not close when 
closing the parent MemorySegment from which it came from. This segment 
will always report that it is alive unless closed itself but if the File 
backed by the MappedMemorySegment is closed it will crash the JVM on 
read/write access. You can make it usable again by loading the File 
backed by the previous MappedMemorySegment into memory again. Of note is 
that the new MappedMemorySegment can be 1 byte even though, for example, 
8 bytes was carved out of the same file before.


If this isn't known about already then it would be nice if it was made 
part of the official API by adding an "isTethered()" method to 
MappedMemorySegment. I'm not 100% what's going on internally here in 
terms of memory state, my guess is that if the File backing a 
MappedMemorySegment isn't in memory then no memory is consumed even 
though the MemorySegment's return true for an alive state. The 
documentation for isAlive doesn't define what being "alive" means.


Here is code to produce this:


File file = new File("./test.txt");

         if(!file.exists())
             file.createNewFile();
         else
         {
             file.delete();
             file.createNewFile();

         }

         VarHandle handle = MemoryHandles.varHandle(long.class, 
ByteOrder.nativeOrder());

         MappedMemorySegment segment = 
MemorySegment.mapFromPath(file.toPath(), 0, 128, 
FileChannel.MapMode.READ_WRITE);

         MemorySegment sliceSegment = segment.asSlice(0, 8);

         handle.set(sliceSegment.baseAddress(), 20);

         MemorySegment unsafeSliceSegment = 
MemorySegment.ofNativeRestricted(
                 sliceSegment.baseAddress(),
                 CSupport.C_LONGLONG.byteSize(),
                 null,
                 null,
                 null
         );

         segment.force();
         segment.unload();
         segment.close();

         System.out.println("Big Segment Alive? " + segment.isAlive()); 
// prints false
         System.out.println("Sliced Segment Alive? " + 
sliceSegment.isAlive()); // prints false
         System.out.println("Unsafe Sliced Segment Alive? " + 
unsafeSliceSegment.isAlive()); // prints true

         // Removing this line gives a JVM crash on access of 
unsafeSliceSegment
         segment = MemorySegment.mapFromPath(file.toPath(), 0, 128, 
FileChannel.MapMode.READ_WRITE);

System.out.println(handle.get(unsafeSliceSegment.baseAddress()));



More information about the panama-dev mailing list