How to prevent an object from getting garbage collected?

后端 未结 11 1928
太阳男子
太阳男子 2020-12-02 13:17

How to prevent an object from getting garbage collected?

Are there any approaches by finalize or phantom reference or any other approaches?

I was asked this

11条回答
  •  既然无缘
    2020-12-02 13:54

    The best way is to use Unsafe, although ByteBuffer might be a possible workaround for some cases.

    Also search for the keyword "off-heap" memory.

    Unsafe

    Advantages over ByteBuffer:

    • allows objects to be represented directly, without for serialization and thus faster
    • no bounds checking, so faster
    • explicit deallocation control
    • can allocate more than the JVM limit

    It is not however easy to get working. The method is described in the following articles:

    • http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
    • https://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/
    • http://java.dzone.com/articles/understanding-sunmiscunsafe

    They all consist of the following steps:

    • we need a sizeof operator, which Unsafe does not have. How to make one was asked at: In Java, what is the best way to determine the size of an object?. The best options is likely the instrument API, but that requires you to create a Jar and use special command line options...

    • once we have sizeof, allocate enough memory with Unsafe#allocateMemory, which is basically a malloc and returns an address

    • create a regular on heap object, copy it to the allocated memory with Unsafe#copyMemory. To do this, you need to the address of the on-heap object, and the size of the object

    • set an Object to point to the allocated memory, then cast the Object to your class.

      It does not seem possible to set the address of a variable directly with Unsafe, so we need to wrap the object into an array or wrapper object, and use Unsafe#arrayBaseOffset or Unsafe#objectFieldOffset.

    • once you are done, free the allocated memory with freeMemory

    If I ever get this to not segfault I will post an example :-)

    ByteBuffer

    Advantages over Unsafe:

    • stable across Java versions while Unsafe may break
    • does bound checking, so safer than... Unsafe, which allows for memory leaks and SIGSEGV

    JLS says:

    The contents of direct buffers may reside outside of the normal garbage-collected heap.

    Example of usage with primitives:

    ByteBuffer bb = ByteBuffer.allocateDirect(8);
    
    bb.putInt(0, 1);
    bb.putInt(4, 2);
    assert bb.getInt(0) == 1;
    assert bb.getInt(4) == 2;
    
    // Bound chekcs are done.
    boolean fail = false;
    try {
        bb.getInt(8);
    } catch(IndexOutOfBoundsException e) {
        fail = true;
    }
    assert fail;
    

    Related threads:

    • Difference between "on-heap" and "off-heap"

提交回复
热议问题