JAVA NIO memory leak

foreword

When writing NIO programs, ByteBuffer is often used to read and write data. Should we use ByteBuffer.allocate() or ByteBuffer.allocateDirect for allocation?

  • allocate() allocates jvm heap memory, which belongs to the category of GC management and requires in-heap copy, which is slow.
  • allocateDirect() directly allocates off-heap memory, which belongs to the OS category, has no GC management, and is faster.

We would like to use a faster way, but no GC management would create OOM issues.

Fortunately, there is a DirectByteBuffer in java corresponding to the OS memory. When the GC occurs, this class will be recycled, and the corresponding OS memory will be recycled, which satisfies our idea. But if the heap is always enough, the GC is not triggered, and the DirectByteBuffer does not perform the GC? The corresponding OS memory will not be recycled.

Since the automatic GC method is unreliable, fortunately there is a Cleaner object in DirectByteBuffer, which has a clean() method, through which we can release it manually.

test

  1. Allocate -Xmx=100m, without setting -XX:MaxDirectMemorySize, the default size is the same as -Xmx size

    //Allocate 128MB direct memory ByteBuffer bb = ByteBuffer.allocateDirect(1024 1024 128);

generate OOM;

  1. Set JVM parameters -Xmx256m -XX:MaxDirectMemorySize=100M

The same code produces OOM;

  1. Manual release

public static void main(String[] args) throws InterruptedException{ //分配512MB直接缓存 ByteBuffer bb = ByteBuffer.allocateDirect(10241024512);

    TimeUnit.SECONDS.sleep(10);
     
    //清除直接缓存
    ((DirectBuffer)bb).cleaner().clean();
     
    TimeUnit.SECONDS.sleep(10);
     
    System.out.println("ok");
}

Then, by observing the changes in memory usage, it was found that the memory increased from the previous time until after calling clean(), and the memory decreased, indicating that the clean() method took effect.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324425342&siteId=291194637