• Direct memory is not part of the runtime data area of the virtual machine, nor is it a memory area defined in the Java Virtual Machine Specification
  • Direct memory is the memory space outside the Java heap that is requested directly from the system
  • Is derived from theNIO, by existing in the heapDirectByteBufferOperating Native memory
  • In general, access to direct memory will be faster than the Java heap, which means better read and write performance. Therefore, for performance reasons, direct memory may be considered in situations where read and write operations are frequent. Java’s NIO library allows Java programs to use direct memory for data buffers

To read and write files, you need to interact with disks and switch from user mode to kernel mode. In kernel mode, memory is required to perform the following operations. Using IO, two copies of memory are required to store duplicate data, which is inefficient

With NIO, as shown in the figure, there is only one copy of the direct cache delineated by the operating system that can be accessed directly by Java code. NIO is suitable for reading and writing large files

Code test IO and NIO to copy large files for three times

```java package com.nasuf.jvm; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; Public class BufferTest {private static final String TO = "/ Users/nasuf/Downloads/pycharm - community - 2021.1.1. DMG"; private static final int _100MB = 1024 * 1024 * 100; public static void main(String[] args) { long sum = 0; String SRC = "/ Users/nasuf/Downloads/pycharm - community - 2021.1.1. DMG"; For (int I = 0; i < 3; I++) {String dest = "/ Users/nasuf/Downloads/pycharm - community - 2021.1.1." + I + "DMG"; // sum += io(src, dest); Sum += directBuffer(SRC, dest); } system.out. println(" system.out. println "); } private static long directBuffer(String src, String dest) { long start = System.currentTimeMillis(); FileChannel inChannel = null; FileChannel outChannel = null; try { inChannel = new FileInputStream(src).getChannel(); outChannel = new FileOutputStream(dest).getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_100MB); while (inChannel.read(byteBuffer) ! = -1) { byteBuffer.flip(); // Change to read data mode outchannel.write (byteBuffer); byteBuffer.clear(); }} catch (IOException e) {e.printStackTrace(); } finally { if (inChannel ! = null) { try { inChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if (outChannel ! = null) { try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } long end = System.currentTimeMillis(); return end - start; } private static long io(String src, String dest) { long start = System.currentTimeMillis(); FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(src); fos = new FileOutputStream(dest); byte[] buffer = new byte[_100MB]; while (true) { int len = fis.read(buffer); if (len == -1) { break; } fos.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis ! = null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos ! = null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } long end = System.currentTimeMillis(); return end - start; }} ` ` `Copy the code
  • Direct memory can also causeOutOfMemoryErrorabnormal

    Code test direct memory OOM exception

    package com.nasuf.jvm;
    
    import java.nio.ByteBuffer;
    import java.util.ArrayList;
    
    public class BufferTest2 {
        private static final int BUFFER = 1024 * 1024 * 20; // 20MB
    
        public static void main(String[] args) {
            ArrayList<ByteBuffer> list = new ArrayList<>();
    
            int count = 0;
            try {
                while (true) { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER); list.add(byteBuffer); count++; }}finally{ System.out.println(count); }}}Copy the code

    The output is as follows:

    182
    Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
            at java.nio.Bits.reserveMemory(Bits.java:693)
            at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
            at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
            at com.nasuf.jvm.BufferTest2.main(BufferTest2.java:15)
    Copy the code
  • Since direct internals reside outside the Java heap, its size is not directly limited-XmxSpecifies the maximum heap size, but system memory is limited, and the sum of the Java heap and direct memory is still limited by the maximum memory the operating system can give
  • disadvantages
    • Distribution recovery costs are high
    • It is not managed by JVM memory reclamation
  • Direct memory size can be passedMaxDirectMemorySizeSettings; If not specified, defaults to the maximum value of the heap-XmxConsistent parameter values
  • Java Process Memory = Java Heap + Native Memory