package org.voovan.tools;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Cleaner 非对内存释放类
 *
 * @author: helyho
 * Voovan Framework.
 * WebSite: https://github.com/helyho/Voovan
 * Licence: Apache v2 License
 */
public class Cleaner extends PhantomReference<Object> {
    private static final ReferenceQueue<Object> dummyQueue = new ReferenceQueue();
    private static Cleaner first = null;
    private Cleaner next = null;
    private Cleaner prev = null;
    private final Runnable thunk;
    private static final Timer timer;

    static {

        Integer noHeapReleaseInterval = TProperties.getInt("framework", "NoHeapReleaseInterval");
        noHeapReleaseInterval = noHeapReleaseInterval ==0 ? 30 : noHeapReleaseInterval;
        timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                while(true) {
                    Reference cleanerRef= dummyQueue.poll();
                    if(cleanerRef == null){
                        break;
                    } else if(cleanerRef instanceof Cleaner){
                        Cleaner cleaner = (Cleaner) cleanerRef;
                        cleaner.clean();
                    }
                }
            }
        }, 1000, noHeapReleaseInterval*1000);
    }

    private static synchronized Cleaner add(Cleaner cleaner) {
        if (first != null) {
            cleaner.next = first;
            first.prev = cleaner;
        }

        first = cleaner;
        return cleaner;
    }

    private static synchronized boolean remove(Cleaner cleaner) {
        if (cleaner.next == cleaner) {
            return false;
        } else {
            if (first == cleaner) {
                if (cleaner.next != null) {
                    first = cleaner.next;
                } else {
                    first = cleaner.prev;
                }
            }

            if (cleaner.next != null) {
                cleaner.next.prev = cleaner.prev;
            }

            if (cleaner.prev != null) {
                cleaner.prev.next = cleaner.next;
            }

            cleaner.next = cleaner;
            cleaner.prev = cleaner;
            return true;
        }
    }


    private Cleaner(Object obj, Runnable thunk) {
        super(obj, dummyQueue);
        this.thunk = thunk;
    }



    public static Cleaner create(Object obj, Runnable thunk) {
        return thunk == null ? null : add(new Cleaner(obj, thunk));
    }


    public void clean() {
        if (remove(this)) {
            try {
                this.thunk.run();
            } catch (final Throwable var2) {
                System.out.println("Cleaner terminated abnormally");
            }
        }
    }
}

@@ -765,17 +765,30 @@
         
-n
+Integer finalN
 oHeapRel
@@ -831,17 +831,16 @@
  ==0 ? 3
-0
  : noHea
@@ -887,16 +887,17 @@
 mer();%0A%0A
+%0A
         
@@ -925,24 +925,59 @@
 merTask() %7B%0A
+            int releaseCount = 0;%0A%0A
             
@@ -1152,16 +1152,198 @@
 = null)%7B
+%0A%0A                        if(releaseCount == finalNoHeapReleaseInterval)%7B%0A                            System.gc();%0A                        %7D%0A%0A                        releaseCount ++;
 %0A       
@@ -1529,24 +1529,66 @@
 er.clean();%0A
+                        releaseCount = 0;%0A
             
@@ -1621,32 +1621,32 @@
 %7D%0A            %7D%0A
+
         %7D, 1000,
@@ -1650,30 +1650,8 @@
 00, 
-noHeapReleaseInterval*
 1000

优化日志的 Cleaner 内存控制