MemorySegment JVM memory leak
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Apr 20 13:15:33 UTC 2020
Hi,
I've tried your example and I think it's running as expected. With a
little caveat (described below).
On my machine, the test completes - with resident memory pegged at
about 8G, while virtual memory was 100G. The latter is normal, since in
order to make the memory accessible to your process, mmap has to reserve
100G memory in the virtual address space. These 100G will not of course
be committed all at once - the policy by which this is done is heavily
OS dependent. Most OS will have some logic in order to discard unused
pages, so that your application will not crash; also, most OS will also
attempt to "prefetch" more than one page in order to speed up access.
Now, what's puzzling is why the resident memory is so high - and I think
I found out what happens: basically this test is generating an awful lot
of dirty pages - since these pages are not flushed back to disk (e.g. in
a way similar to what MappedByteBuffer::force does), all these pages
have to be kept around for longer in main memory (again, the details and
thresholds are system specific).
Since I'm in the middle of adding force() support to mapped segments:
https://git.openjdk.java.net/panama-foreign/pull/115
I did a simple experiment: I added a call to the new
MappedMemorySegment::force() after the call to MemoryAddress::copy, and
re-ran the test. And now the resident memory was pegged at 150KB :-)
So, I believe your issue is that, when managing very large file you have
to be disciplined in how you sync contents of main memory back into the
mapped file - if you leave it implicit (e.g. to the OS), you might end
up in a not-so-desirable place.
Does this help?
Maurizio
On 18/04/2020 17:33, ahmdprog.java at gmail.com wrote:
> Gentlemen,
>
>
>
> There is memory leak in JVM while writing and reading byte array to memory
> segment. The below is simple example that generates 100G file with zero
> bytes. While running the below code, you will see that JVM consumes all
> server memory.
>
>
>
> Unfortunately, I tested also in reading array of bytes. It has same issue of
> memory leak.
>
>
>
>
>
> public static void testingMemorySegment() {
>
> String strFileName = "/disk3/bigdata.index" +
> System.currentTimeMillis();
>
> File fileObjectFileName = new File(strFileName);
>
> if (fileObjectFileName.exists() == false) {
>
> try {
>
> fileObjectFileName.createNewFile();
>
> } catch (IOException e) {
>
> } catch (Exception e) {
>
> }
>
> }
>
> long lngMemorySegmentFileSize = 107374182400l; // 100 G
>
> byte[] bytesArrayString = new byte[4096];
>
> MemorySegment sourceSegment =
> MemorySegment.ofArray(bytesArrayString);
>
> long lngTotalNumberOfPagesForAllFile = lngMemorySegmentFileSize /
> 4096;
>
> try {
>
> MemorySegment memorySegmentTmp = MemorySegment.mapFromPath(new
> File(strFileName).toPath(), lngMemorySegmentFileSize,
> FileChannel.MapMode.READ_WRITE);
>
> MemoryAddress address = memorySegmentTmp.baseAddress();
>
> MemoryAddress sourceAddress = sourceSegment.baseAddress();
>
> for (long i = 0; i < lngTotalNumberOfPagesForAllFile; i++) {
>
> MemoryAddress.copy(sourceAddress, address.addOffset(i *
> 4096), 4096);
>
> }
>
> memorySegmentTmp.close();
>
> } catch (IOException e) {
>
> e.printStackTrace();
>
> }
>
> }
>
More information about the panama-dev
mailing list