How to garbage collect a direct buffer in Java

前端 未结 6 1811
遥遥无期
遥遥无期 2020-12-05 00:02

I have a memory leak that I have isolated to incorrectly disposed direct byte buffers.

ByteBuffer buff = ByteBuffer.allocateDirect(7777777);

The GC colle

6条回答
  •  感情败类
    2020-12-05 00:55

    The DBB will be deallocated once it hits the reference queue, and the finalizer is run. However, as we cannot depend on a finalizer to run, we can use reflection to manually call its "cleaner".

    Using reflection:

    /**
    * DirectByteBuffers are garbage collected by using a phantom reference and a
    * reference queue. Every once a while, the JVM checks the reference queue and
    * cleans the DirectByteBuffers. However, as this doesn't happen
    * immediately after discarding all references to a DirectByteBuffer, it's
    * easy to OutOfMemoryError yourself using DirectByteBuffers. This function
    * explicitly calls the Cleaner method of a DirectByteBuffer.
    * 
    * @param toBeDestroyed
    *          The DirectByteBuffer that will be "cleaned". Utilizes reflection.
    *          
    */
    public static void destroyDirectByteBuffer(ByteBuffer toBeDestroyed)
        throws IllegalArgumentException, IllegalAccessException,
        InvocationTargetException, SecurityException, NoSuchMethodException {
    
      Preconditions.checkArgument(toBeDestroyed.isDirect(),
          "toBeDestroyed isn't direct!");
    
      Method cleanerMethod = toBeDestroyed.getClass().getMethod("cleaner");
      cleanerMethod.setAccessible(true);
      Object cleaner = cleanerMethod.invoke(toBeDestroyed);
      Method cleanMethod = cleaner.getClass().getMethod("clean");
      cleanMethod.setAccessible(true);
      cleanMethod.invoke(cleaner);
    
    }
    

提交回复
热议问题