Netty Source code-seven, memory release

Source: Internet
Author: User

Netty itself supports heap memory and direct memory on memory allocations, and we generally choose Direct memory, which is also the default configuration. So to understand the release of Netty memory we have to look at the release of direct memory first.

Java Direct Memory Release

Let's take a look at how direct memory is used.

ByteBuffer.allocateDirect(capacity)

The application process is actually the process of creating a Directbytebuffer object, the Directbytebuffer object is only equivalent to a holder, contains an address, this is a direct memory pointer.

    • Call the native method to request memory
    • Initialize Cleaner
public static ByteBuffer allocateDirect(int capacity) {    return new DirectByteBuffer(capacity);}DirectByteBuffer(int cap) {                   // package-private    // 省略中间代码...    // 创建一个cleaner,最后会调用Deallocator.run来释放内存    cleaner = Cleaner.create(this, new Deallocator(base, size, cap));    att = null;}

Cleaner This class inherits from Phantomreference, the so-called virtual reference, which is characterized by the following types of references:

    • You cannot get to an object by using the Get method
    • As long as the referenced object has no other references other than Phantomreference, the JVM can recycle the objects referenced by phantomreference at any time.

The JVM will put the object to be reclaimed in a queue before returning, because cleaner inherits from Phantomreference, the implementation of the queue is using Cleaner's

private static final ReferenceQueue<Object> dummyQueue = new ReferenceQueue<>();

This queue is used in the parent class reference of Phantomreference, reference this class initiates a thread to invoke the Cleaner.clean method at initialization time, and starts the threads in reference static code block

// java.lang.ref.Referencestatic {    ThreadGroup tg = Thread.currentThread().getThreadGroup();    for (ThreadGroup tgn = tg;         tgn != null;         tg = tgn, tgn = tg.getParent());    Thread handler = new ReferenceHandler(tg, "Reference Handler");    /* If there were a special system-only priority greater than         * MAX_PRIORITY, it would be used here         */    handler.setPriority(Thread.MAX_PRIORITY);    handler.setDaemon(true);    // 启动ReferenceHandler线程    handler.start();    // 省略中间代码...}

The main function of this thread is to call tryhandlepending

Java.lang.ref.reference#tryhandlependingstatic Boolean tryhandlepending (Boolean waitfornotify) {Reference<Ob        Ject> R;        Cleaner C;                    try {synchronized (lock) {if (pending! = null) {r = pending; ' instanceof ' might throw outofmemoryerror sometimes//so does this before un-linking ' R ' from The ' pending ' chain ... c = r instanceof Cleaner?                    (Cleaner) R:null;                    Unlink ' R ' from ' pending ' chain pending = r.discovered;                r.discovered = null; } else {//The waiting on the lock cause a outofmemoryerror//because it may                    Try to allocate exception objects.                    if (waitfornotify) {lock.wait ();                }//Retry if waited return waitfornotify;        }    }} catch (OutOfMemoryError x) {//Give other threads CPU time so they hopefully drop some live ref            Erences//And GC reclaims some space. Also prevent CPU Intensive spinning in case ' r instanceof Cleaner ' above//persistently throws Oome for Som            E-time ...            Thread.yield ();        Retry return true;        } catch (Interruptedexception x) {///retry return true;            }//Fast path for Cleaners if (c! = null) {//Call the Clean Method C.clean ();        return true; } referencequeue<?        Super object> q = r.queue;        if (q! = referencequeue.null) Q.enqueue (R); return true;}

System.GC cannot reclaim out-of-heap memory, but it recycles unused directbytebuffer objects, which are recycled to put cleaner objects in the queue, and the clean method is called in the reference thread to reclaim the out-of-heap memory. Cleaner.run executes the Thunk.run method that passes in the parameter, here thunk is Deallocator, so the last Deallocator.run method to execute

public void run() {    if (address == 0) {        // Paranoia        return;    }    // 释放内存    unsafe.freeMemory(address);    address = 0;    Bits.unreserveMemory(size, capacity);}

So finally, the requested memory was released through Unsafe.freememory.

To summarize, when requesting memory, the call isjava.nio.ByteBuffer#allocateDirect

will be new Directbytebuffer, Cleaner is created through Cleaner.create, and Deallocator is passed as the runnable parameter, which is called when Cleaner.clean is used to handle

Cleaner inherits from Phantomreference and contains a referencequeue that is in the Java heap when the Directbytebuffer is no longer in use. In addition to the Phantomreference reference to Directbytebuffer, when there are no other references, the JVM puts cleaner objects in the Referencequeue queue.

Phantomreference inherits the Reference,reference will start a thread (java.lang.ref.reference.referencehandler# Run) to call the Cleaner.clean method in the queue.

Netty Memory Release

The direct memory used by Netty is released in a slightly different way from the JDK. Netty starts releasing memory when the free method is called

io.netty.buffer.PoolArena#freeio.netty.buffer.PoolArena.DirectArena#destroyChunk

There are two ways to eventually release memory

    1. Use reflection to get unsafe, call Unsafe#freememory
    2. Get Directbytebuffer#cleaner with reflection, call the Cleaner.clean method with reflection

Two different ways to rely on different conditions, the use of the scene is also different

Call Cleaner.clean Using Reflection

Use this method when you want to meet one of the following conditions

    1. No direct memory to use
    2. Cannot get unsafe
    3. Directbuffer does not pass a long, int construction method
Using unsafe

Do not use unsafe in this way

Netty Source code-seven, memory release

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.