Java Memory Mapped Files

How shared memory and memory-mapped files function on Windows operating systems.

  1. Java Memory Mapped Files Size
  2. Mappedbytebuffer
  3. Java Memory Mapped File Write
  4. Java Memory Mapped File Performance

Join the DZone community and get the full member experience.

Jan 04, 2012  Memory Mapped Files in Java is rather new java concept for many programmers and developers, though it’s been there from JDK 1.4 along with java.nio package. Java IO has been considerably fast after the introduction of NIO and memory mapped file offers fastes t IO operation possible in Java, that's the main reason of Why high-performance Java application should use Memory. Jun 19, 2002  Bridge: Named Memory Mapped Files. You can use window messages like WMCOPYDATA, pipe, sockets (just name a few) to share data between different processes on the same machine. But the most efficient way is to use memory mapped files. Because all the mechanisms mentioned above are using the memory mapped files internally, to do the dirty work. Nov 17, 2013  Important Points of Memory Mapped IO in Java. Here are some of the important facts to know about Memory Mapped File in Java: Java supports Memory mapped IO with java.nio package. Memory mapped files is used in performance sensitive application, e.g. Memory-mapped files. Memory-mapped files allow you to create and modify files that are too big to bring into memory. With a memory-mapped file, you can pretend that the entire file is in memory and that you can access it by simply treating it as a very large array. I was reading the book and it has got the below lines: A MemoryMappedBuffer directly reflects the disk file with which it is associated. If the file is structurally modified while the mapping.

Join For Free

I am often asked why memory-mapped files can be more efficient than plain read/write I/O calls, and whether shared memory is slower than private memory. These seemingly unrelated mechanisms share a common implementation in the Windows kernel, known as section objects or file mapping objects. Yes, this shared implementation powers memory pages that are shared across multiple processes (by name) as well as file regions mapped to memory pages (even in a single process).

If you’re interested in a thorough discussion of how section objects work, I must refer you to Windows Internals, 6th Edition. But if you’re only here for the quick answers and myth-busting, read on; I promise that in just over 650 words you’ll have what you came for.

On Memory-Mapped Files

Java Memory Mapped Files Size

When you map a file to memory, you instruct the Windows memory manager to create a data structure that maps a region of virtual memory pages in your process’ address space to a region of a file on disk. More specifically, the memory manager marks the virtual memory region as invalid from the processor’s perspective, but sets aside some book-keeping information that describes the mapping (in data structures known as section control areas, segments, and subsections).

Protestant Amharic Musmur Download Free Mp3 Song. ምርጥ የአማርኛ መዝሙሮች ስብስብ #1 (Amharic. Worship Songs የአምልኮ መዝሙሮች (mezmur) Ethiopian Protestant songs mp3 Quality: Good Download. YOSEF KASSA NEW MUSIC 2019 (OFFICIAL MUSIC VIDEO )ይሄ ነው የገባኝYihe Nen Yegebagn mp3 Quality. Audio For your search query Mezmur Orthodox Ethiopia MP3 we have found 1000000 songs matching your query but showing only top 10 results. Now we recommend you to Download first result ውዳሴ ማርያም መዝሙሮች Mariam Amalaje Mezmuroch Ethiopian Orthodox Spiritual Songs Collection MP3 which is uploaded by Arsema Tube of size 104.21 MB, duration 1 hour, 19 minutes and 11 seconds.

Next, when your application accesses one of the virtual addresses mapped to the file, the processor generates an exception. The memory manager handles the exception by performing an on-demand read from the file to a newly allocated physical memory page, and remaps the virtual page to that physical page. As a result, your application can now access that page of virtual memory as usual, and it will have the contents of the file on disk.

Why is this any more efficient or useful than just calling a read API, such as the Win32 ReadFile or the .NET FileStream.Read? There are numerous reasons:

After a page has already been fetched from disk, subsequent accesses will not require any intervention on the OS’s behalf. You simply read and write memory. On the other hand, when you use file manipulation APIs, you incur a system call, which is several orders of magnitude more expensive.

Accesses to a memory mapped file will not require additional buffers to be allocated and freed by your program. The system manages the physical memory for the mapped file, and you don’t have to allocate a read or write buffer and copy data an extra time.

When working with other libraries designed to manipulate memory addresses directly, you can easily (and with no additional overhead) provide the base address for a memory-mapped file to the library functions. For example, to copy data from one region of the file to another, you can simply use memcpy instead of a loop that performs read and write operations and manipulates seek pointers. Similarly, the Windows image loader simply maps DLLs into memory so that when a function in your DLL invokes another function which isn’t resident, it is transparently loaded from disk as necessary. (This is a simplified picture that ignores relocations, but you get the idea.)

This is not to say that memory-mapped files are without disadvantages. For example, asynchronous I/O doesn’t play well with memory-mapped files (when you read or write a memory location, you don’t have the luxury of specifying a continuation or doing anything else while the page is fetched). But there are a great many cases when memory-mapped files can be extremely effective, and these are often overlooked by Windows developers.

On Shared Memory

Section objects are also used to share memory between processes. When one process names a section object, another process may open a handle to it by using the same name (given the appropriate access rights). Both processes can then map regions of that section object to their respective virtual address spaces. After both processes have done so, each process will have a region of virtual memory pages mapped to the shared region of physical memory pages.

Note that the section object might be based on a file on disk, in which case you have a memory-mapped file shared across processes: this is what the OS image loader does with DLLs. Or, the section object may not be based on a file on disk, in which case it is purely a shared memory region backed by the page file, if present.

Neither your application nor the CPU has to care whether the memory pages are shared with another process or not. In fact, from the CPU’s perspective, accessing a memory page that just happens to be mapped in some other process is exactly the same as accessing a private page. The end result is that shared memory is just as fast as private memory; the hardware simply doesn’t care if it is or isn’t shared.

Like This Article? Read More From DZone

windows ,memory ,internals

Published at DZone with permission of Sasha Goldshtein , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Active9 months ago

I am mapping a file('sample.txt') to memory using FileChannel.map() and then closing the channel using fc.close(). After this when I write to the file using FileOutputStream, I am getting the following error:

java.io.FileNotFoundException: sample.txt (The requested operation cannot be per formed on a file with a user-mapped section open)

I presume this may be due to file being still mapped to the memory even after I close the FileChannel. Am I right?. If so, how can I 'unmap' the file from memory?(I can't find any methods for this in the API).Thanks.

Edit:Looks like it(adding an unmap method) was submitted as RFE to sun some time back:http://bugs.sun.com/view_bug.do?bug_id=4724038

learner135
learner135learner135

12 Answers

From the MappedByteBuffer javadoc:

A mapped byte buffer and the file mapping that it represents remain valid until the buffer itself is garbage-collected.

Try calling System.gc()? Even that's only a suggestion to the VM.

Edward DaleEdward Dale
23.2k9 gold badges81 silver badges125 bronze badges

Following static method could be used:

But this is unsafe solution because of following:
1) Lead to failures if someone use MappedByteBuffer after unmap
2) It relies on MappedByteBuffer implementation details

Timur YusupovTimur Yusupov
5981 gold badge6 silver badges10 bronze badges

[WinXP,SunJDK1.6] I had a mapped ByteBuffer taken from filechannel. After reading SO posts finally managed to call a cleaner through reflection without any sun.* package imports. No longer file lock is lingering.

edit Added JDK9+ code(Luke Hutchison).

Ideas were taken from these posts.
* How to unmap a file from memory mapped using FileChannel in java?
* Examples of forcing freeing of native memory direct ByteBuffer has allocated, using sun.misc.Unsafe?
* https://github.com/elasticsearch/elasticsearch/blob/master/src/main/java/org/apache/lucene/store/bytebuffer/ByteBufferAllocator.java#L40

WhomeWhome
8,1803 gold badges31 silver badges57 bronze badges

sun.misc.Cleaner javadoc says:

General-purpose phantom-reference-based cleaners. Cleaners are a lightweight and more robust alternative to finalization. They are lightweight because they are not created by the VM and thus do not require a JNI upcall to be created, and because their cleanup code is invoked directly by the reference-handler thread rather than by the finalizer thread. They are more robust because they use phantom references, the weakest type of reference object, thereby avoiding the nasty ordering problems inherent to finalization. A cleaner tracks a referent object and encapsulates a thunk of arbitrary cleanup code. Some time after the GC detects that a cleaner's referent has become phantom-reachable, the reference-handler thread will run the cleaner. Cleaners may also be invoked directly; they are thread safe and ensure that they run their thunks at most once. Cleaners are not a replacement for finalization. They should be used only when the cleanup code is extremely simple and straightforward. Nontrivial cleaners are inadvisable since they risk blocking the reference-handler thread and delaying further cleanup and finalization.

Running System.gc() is acceptable solution if your buffers total size is small, but if I was mapping gigabytes of files I would try to implement like this:

But! Make sure you don't access that buffer after cleaning or you will end up with:

A fatal error has been detected by the Java Runtime Environment: EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000002bcf700, pid=7592, tid=10184 JRE version: Java(TM) SE Runtime Environment (8.0_40-b25) (build 1.8.0_40-b25) Java VM: Java HotSpot(TM) 64-Bit Server VM (25.40-b25 mixed mode windows-amd64 compressed oops) Problematic frame: J 85 C2 java.nio.DirectByteBuffer.get(I)B (16 bytes) @ 0x0000000002bcf700 [0x0000000002bcf6c0+0x40] Failed to write core dump. Minidumps are not enabled by default on client versions of Windows An error report file with more information is saved as: C:Users?????ProgramstestApphs_err_pid7592.log Compiled method (c2) 42392 85 4 java.nio.DirectByteBuffer::get (16 bytes) total in heap [0x0000000002bcf590,0x0000000002bcf828] = 664 relocation [0x0000000002bcf6b0,0x0000000002bcf6c0] = 16 main code [0x0000000002bcf6c0,0x0000000002bcf760] = 160 stub code
[0x0000000002bcf760,0x0000000002bcf778] = 24 oops
[0x0000000002bcf778,0x0000000002bcf780] = 8 metadata
[0x0000000002bcf780,0x0000000002bcf798] = 24 scopes data
[0x0000000002bcf798,0x0000000002bcf7e0] = 72 scopes pcs
[0x0000000002bcf7e0,0x0000000002bcf820] = 64 dependencies
[0x0000000002bcf820,0x0000000002bcf828] = 8

Good luck!

Files
Dmytro VoloshynDmytro Voloshyn

To work around this bug in Java, I had to do the following, which will work ok for small to medium-sized files:

Mr EdMr Ed
4,5381 gold badge15 silver badges11 bronze badges

The mapped memory is used until it is freed by the garbage collector.

From FileChannel docs

A mapping, once established, is not dependent upon the file channel that was used to create it. Closing the channel, in particular, has no effect upon the validity of the mapping.

From MappedByteBuffer java doc

A mapped byte buffer and the file mapping that it represents remain valid until the buffer itself is garbage-collected.

So I would suggest ensuring there are no remaining references to the mapped byte buffer and then requesting a garbage collection.

BenMBenM
3,6331 gold badge19 silver badges26 bronze badges

I found out information about unmap, it is a method of FileChannelImpl and not accessible, so you can invoke it by java reflect like:

饒夢楠饒夢楠

The method covered in other answers that employs ((DirectBuffer) byteBuffer).cleaner().clean() doesn't work on JDK 9+ (even in reflective form) without displaying an An illegal reflective access operation has occurred warning. This will stop working altogether in some future JDK version. Fortunately sun.misc.Unsafe.invokeCleaner(ByteBuffer) can make that exact same call for you without the warning: (from OpenJDK 11 source):

Being a sun.misc class, it will be removed at some point. Interestingly all calls but this one in sun.misc.Unsafe are proxied directly to jdk.internal.misc.Unsafe (I don't know why invokeCleaner(ByteBuffer) is not proxied in the same way as all the other methods -- it was probably an accidental omission).

I wrote the following code that is able to clean/close/unmap DirectByteBuffer/MappedByteBuffer instances on JDK 7/8, as well as JDK 9+, and this does not give the reflection warning:

Note that you will need to add the requires jdk.unsupported to your module descriptor in a modular runtime on JDK 9+ (needed for the use of Unsafe).

Your jar may also need RuntimePermission('accessClassInPackage.sun.misc'), RuntimePermission('accessClassInPackage.jdk.internal.misc'), and ReflectPermission('suppressAccessChecks').

Luke HutchisonLuke Hutchison

Mappedbytebuffer

3,7251 gold badge21 silver badges22 bronze badges

It is funny to see so many recommendations to do what Item 7 in 'Effective Java' specifically says not to do. A termination method like what @Whome did and no references to the buffer is what is needed. GC cannot be forced.But that doesn't stop developers from trying. Another workaround I found was to use WeakReferences from http://jan.baresovi.cz/dr/en/java#memoryMap

Droid TeahouseDroid Teahouse

I would try JNI:

File

Include files: windows.h for Windows, sys/mmap.h for BSD, Linux, OSX.

martinsmartins

Java Memory Mapped File Write

If the mapped file buffer object can be guaranteed to be eligible for garbage collection, you don't need to GC the whole VM to get the buffer's mapped memory to be released. You can call System.runFinalization() . This will call the finalize() method on the mapped file buffer object (if it there are no references to it in your app threads) which will release the mapped memory.

somedudesomedude

The correct solution here is to use try-with-resources.

Java Memory Mapped File Performance

This allows the creation of the Channel & the other resources to be scoped to a block. Once the block exits, the Channel & other resources are gone & subsequently cannot be used (as nothing has a reference to them).

The memory-mapping still won't be undone until the next GC run, but at least there aren't any dangling references to it.

kittylystkittylyst

Not the answer you're looking for? Browse other questions tagged javamemory-mapped-files or ask your own question.