国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

聊聊GenericObjectPool的泄露檢測(cè)

springDevBird / 819人閱讀

摘要:序本文主要聊聊的參數(shù)。主要用來(lái)做連接池的泄露檢測(cè)用。的狀態(tài)一般是用于連接泄露的檢測(cè),檢測(cè)的是在使用的對(duì)象,比如懷疑那個(gè)對(duì)象被占用時(shí)間超長(zhǎng),那估計(jì)是程序異常或?qū)е聦?duì)象了但忘記歸還,或者對(duì)象之后使用時(shí)間太長(zhǎng)。

本文主要聊聊GenericObjectPool的abandon參數(shù)。主要用來(lái)做連接池的泄露檢測(cè)用。

object的狀態(tài)

commons-pool2-2.4.2-sources.jar!/org/apache/commons/pool2/PooledObjectState.java

public enum PooledObjectState {
    /**
     * In the queue, not in use.
     */
    IDLE,

    /**
     * In use.
     */
    ALLOCATED,

    /**
     * In the queue, currently being tested for possible eviction.
     */
    EVICTION,

    /**
     * Not in the queue, currently being tested for possible eviction. An
     * attempt to borrow the object was made while being tested which removed it
     * from the queue. It should be returned to the head of the queue once
     * eviction testing completes.
     * TODO: Consider allocating object and ignoring the result of the eviction
     *       test.
     */
    EVICTION_RETURN_TO_HEAD,

    /**
     * In the queue, currently being validated.
     */
    VALIDATION,

    /**
     * Not in queue, currently being validated. The object was borrowed while
     * being validated and since testOnBorrow was configured, it was removed
     * from the queue and pre-allocated. It should be allocated once validation
     * completes.
     */
    VALIDATION_PREALLOCATED,

    /**
     * Not in queue, currently being validated. An attempt to borrow the object
     * was made while previously being tested for eviction which removed it from
     * the queue. It should be returned to the head of the queue once validation
     * completes.
     */
    VALIDATION_RETURN_TO_HEAD,

    /**
     * Failed maintenance (e.g. eviction test or validation) and will be / has
     * been destroyed
     */
    INVALID,

    /**
     * Deemed abandoned, to be invalidated.
     */
    ABANDONED,

    /**
     * Returning to the pool.
     */
    RETURNING
}

abandon一般是用于連接泄露的檢測(cè),檢測(cè)的是在使用的對(duì)象,比如懷疑那個(gè)對(duì)象被占用時(shí)間超長(zhǎng),那估計(jì)是程序異常或bug導(dǎo)致對(duì)象borrow了但忘記歸還,或者對(duì)象borrow之后使用時(shí)間太長(zhǎng)。

AbandonedConfig

除了commons-pool2-2.4.2-sources.jar!/org/apache/commons/pool2/impl/GenericObjectPoolConfig.java,還有這個(gè)AbandonedConfig
commons-pool2-2.4.2-sources.jar!/org/apache/commons/pool2/impl/AbandonedConfig.java

public class AbandonedConfig {

    /**
     * Whether or not borrowObject performs abandoned object removal.
     */
    private boolean removeAbandonedOnBorrow = false;

    /**
     * 

Flag to remove abandoned objects if they exceed the * removeAbandonedTimeout when borrowObject is invoked.

* *

The default value is false.

* *

If set to true, abandoned objects are removed by borrowObject if * there are fewer than 2 idle objects available in the pool and * getNumActive() > getMaxTotal() - 3

* * @return true if abandoned objects are to be removed by borrowObject */ public boolean getRemoveAbandonedOnBorrow() { return this.removeAbandonedOnBorrow; } /** *

Flag to remove abandoned objects if they exceed the * removeAbandonedTimeout when borrowObject is invoked.

* * @param removeAbandonedOnBorrow true means abandoned objects will be * removed by borrowObject * @see #getRemoveAbandonedOnBorrow() */ public void setRemoveAbandonedOnBorrow(boolean removeAbandonedOnBorrow) { this.removeAbandonedOnBorrow = removeAbandonedOnBorrow; } /** * Whether or not pool maintenance (evictor) performs abandoned object * removal. */ private boolean removeAbandonedOnMaintenance = false; /** * Timeout in seconds before an abandoned object can be removed. */ private int removeAbandonedTimeout = 300; /** * Determines whether or not to log stack traces for application code * which abandoned an object. */ private boolean logAbandoned = false; /** * PrintWriter to use to log information on abandoned objects. * Use of default system encoding is deliberate. */ private PrintWriter logWriter = new PrintWriter(System.out); /** * If the pool implements {@link UsageTracking}, should the pool record a * stack trace every time a method is called on a pooled object and retain * the most recent stack trace to aid debugging of abandoned objects? */ private boolean useUsageTracking = false; }
參數(shù)

removeAbandonedOnBorrow
在borrow的時(shí)候,是否執(zhí)行abandon判斷,默認(rèn)false

removeAbandonedOnMaintenance
是否在evictor中執(zhí)行abandon判斷,默認(rèn)false

removeAbandonedTimeout
一個(gè)對(duì)象在被borrow之后多少秒未歸還則認(rèn)為是abandon,默認(rèn)為300

logAbandoned
是否打印abandon的日志,默認(rèn)為false

useUsageTracking
是否追蹤對(duì)象調(diào)用并保留最近的調(diào)用記錄方便debug

removeAbandonedOnBorrow

在borrow方法里頭

public T borrowObject(long borrowMaxWaitMillis) throws Exception {
        assertOpen();

        AbandonedConfig ac = this.abandonedConfig;
        if (ac != null && ac.getRemoveAbandonedOnBorrow() &&
                (getNumIdle() < 2) &&
                (getNumActive() > getMaxTotal() - 3) ) {
            removeAbandoned(ac);
        }

        PooledObject p = null;

        // Get local copy of current config so it is consistent for entire
        // method execution
        boolean blockWhenExhausted = getBlockWhenExhausted();

        boolean create;
        long waitTime = System.currentTimeMillis();

        //......

        updateStatsBorrow(p, System.currentTimeMillis() - waitTime);

        return p.getObject();
    }
removeAbandonedOnMaintenance

在evictor線程里頭

public void evict() throws Exception {
        assertOpen();

        if (idleObjects.size() > 0) {

            PooledObject underTest = null;
            EvictionPolicy evictionPolicy = getEvictionPolicy();

            synchronized (evictionLock) {
                EvictionConfig evictionConfig = new EvictionConfig(
                        getMinEvictableIdleTimeMillis(),
                        getSoftMinEvictableIdleTimeMillis(),
                        getMinIdle());

                boolean testWhileIdle = getTestWhileIdle();

                for (int i = 0, m = getNumTests(); i < m; i++) {
                    if (evictionIterator == null || !evictionIterator.hasNext()) {
                        evictionIterator = new EvictionIterator(idleObjects);
                    }
                    if (!evictionIterator.hasNext()) {
                        // Pool exhausted, nothing to do here
                        return;
                    }

                    try {
                        underTest = evictionIterator.next();
                    } catch (NoSuchElementException nsee) {
                        // Object was borrowed in another thread
                        // Don"t count this as an eviction test so reduce i;
                        i--;
                        evictionIterator = null;
                        continue;
                    }

                    if (!underTest.startEvictionTest()) {
                        // Object was borrowed in another thread
                        // Don"t count this as an eviction test so reduce i;
                        i--;
                        continue;
                    }

                    // User provided eviction policy could throw all sorts of
                    // crazy exceptions. Protect against such an exception
                    // killing the eviction thread.
                    boolean evict;
                    try {
                        evict = evictionPolicy.evict(evictionConfig, underTest,
                                idleObjects.size());
                    } catch (Throwable t) {
                        // Slightly convoluted as SwallowedExceptionListener
                        // uses Exception rather than Throwable
                        PoolUtils.checkRethrow(t);
                        swallowException(new Exception(t));
                        // Don"t evict on error conditions
                        evict = false;
                    }

                    if (evict) {
                        destroy(underTest);
                        destroyedByEvictorCount.incrementAndGet();
                    } else {
                        if (testWhileIdle) {
                            boolean active = false;
                            try {
                                factory.activateObject(underTest);
                                active = true;
                            } catch (Exception e) {
                                destroy(underTest);
                                destroyedByEvictorCount.incrementAndGet();
                            }
                            if (active) {
                                if (!factory.validateObject(underTest)) {
                                    destroy(underTest);
                                    destroyedByEvictorCount.incrementAndGet();
                                } else {
                                    try {
                                        factory.passivateObject(underTest);
                                    } catch (Exception e) {
                                        destroy(underTest);
                                        destroyedByEvictorCount.incrementAndGet();
                                    }
                                }
                            }
                        }
                        if (!underTest.endEvictionTest(idleObjects)) {
                            // TODO - May need to add code here once additional
                            // states are used
                        }
                    }
                }
            }
        }
        AbandonedConfig ac = this.abandonedConfig;
        if (ac != null && ac.getRemoveAbandonedOnMaintenance()) {
            removeAbandoned(ac);
        }
    }
removeAbandonedTimeout

在removeAbandoned方法里頭

/**
     * Recover abandoned objects which have been checked out but
     * not used since longer than the removeAbandonedTimeout.
     *
     * @param ac The configuration to use to identify abandoned objects
     */
    private void removeAbandoned(AbandonedConfig ac) {
        // Generate a list of abandoned objects to remove
        final long now = System.currentTimeMillis();
        final long timeout =
                now - (ac.getRemoveAbandonedTimeout() * 1000L);
        ArrayList> remove = new ArrayList>();
        Iterator> it = allObjects.values().iterator();
        while (it.hasNext()) {
            PooledObject pooledObject = it.next();
            synchronized (pooledObject) {
                if (pooledObject.getState() == PooledObjectState.ALLOCATED &&
                        pooledObject.getLastUsedTime() <= timeout) {
                    pooledObject.markAbandoned();
                    remove.add(pooledObject);
                }
            }
        }

        // Now remove the abandoned objects
        Iterator> itr = remove.iterator();
        while (itr.hasNext()) {
            PooledObject pooledObject = itr.next();
            if (ac.getLogAbandoned()) {
                pooledObject.printStackTrace(ac.getLogWriter());
            }
            try {
                invalidateObject(pooledObject.getObject());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

標(biāo)記為abandon之后,立馬放入remove隊(duì)列中,然后遍歷進(jìn)行invalidateObject

public void invalidateObject(T obj) throws Exception {
        PooledObject p = allObjects.get(new IdentityWrapper(obj));
        if (p == null) {
            if (isAbandonedConfig()) {
                return;
            } else {
                throw new IllegalStateException(
                        "Invalidated object not currently part of this pool");
            }
        }
        synchronized (p) {
            if (p.getState() != PooledObjectState.INVALID) {
                destroy(p);
            }
        }
        ensureIdle(1, false);
    }
logAbandoned

最后是作用在這個(gè)類
commons-pool2-2.4.2-sources.jar!/org/apache/commons/pool2/impl/DefaultPooledObject.java

public synchronized boolean allocate() {
        if (state == PooledObjectState.IDLE) {
            state = PooledObjectState.ALLOCATED;
            lastBorrowTime = System.currentTimeMillis();
            lastUseTime = lastBorrowTime;
            borrowedCount++;
            if (logAbandoned) {
                borrowedBy = new AbandonedObjectCreatedException();
            }
            return true;
        } else if (state == PooledObjectState.EVICTION) {
            // TODO Allocate anyway and ignore eviction test
            state = PooledObjectState.EVICTION_RETURN_TO_HEAD;
            return false;
        }
        // TODO if validating and testOnBorrow == true then pre-allocate for
        // performance
        return false;
    }
useUsageTracking
public void use(T pooledObject) {
        AbandonedConfig ac = this.abandonedConfig;
        if (ac != null && ac.getUseUsageTracking()) {
            PooledObject wrapper = allObjects.get(new IdentityWrapper(pooledObject));
            wrapper.use();
        }
    }

就是會(huì)調(diào)用一下PooledObject的use進(jìn)行統(tǒng)計(jì)

commons-pool2-2.4.2-sources.jar!/org/apache/commons/pool2/proxy/BaseProxyHandler.java

    /**
     * Invoke the given method on the wrapped object.
     *
     * @param method    The method to invoke
     * @param args      The arguments to the method
     * @return          The result of the method call
     * @throws Throwable    If the method invocation fails
     */
    Object doInvoke(Method method, Object[] args) throws Throwable {
        validateProxiedObject();
        T object = getPooledObject();
        if (usageTracking != null) {
            usageTracking.use(object);
        }
        return method.invoke(object, args);
    }
doc

commons-pool2 2 - poolObject API與狀態(tài)機(jī)

對(duì)象池common-pool2源碼分析之對(duì)象狀態(tài)

GenericObjectPool 避免泄漏

apache commons pool之GenericObjectPool分析(通用對(duì)象池技術(shù))

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/67838.html

相關(guān)文章

  • GenericObjectPool參數(shù)解析

    摘要:如果為負(fù)值,表示不運(yùn)行檢測(cè)線程。默認(rèn)為策略的類名,默認(rèn)為這里就用到了上面提到的兩個(gè)參數(shù)對(duì)象池原理分析避免泄漏配置參數(shù)詳解,以及資源回收,從池中獲取資源,將資源返還給池邏輯解析 序 本文主要解析一下apache common pools下的GenericObjectPool的參數(shù)設(shè)置 GenericObjectPool commons-pool2-2.4.2-sources.jar!/o...

    huayeluoliuhen 評(píng)論0 收藏0
  • GenericObjectPool 避免泄漏

    摘要:實(shí)際應(yīng)用中由于程序?qū)崿F(xiàn)的問題,可能造成在一些極端的情況下出現(xiàn)沒有被調(diào)用導(dǎo)致的泄漏問題。在的時(shí)候檢查是否有泄漏的時(shí)候檢查泄漏如果一個(gè)對(duì)象之后秒還沒有返還給,認(rèn)為是泄漏的對(duì)象秒運(yùn)行一次維護(hù)任務(wù) 更多內(nèi)容,請(qǐng)?jiān)L問 https://my.oschina.net/u/5751... GenericObjectPool GenericObjectPool 是 Apache Commons Poo...

    Keven 評(píng)論0 收藏0
  • common-pool2 使用

    摘要:使用提供了中對(duì)象池管理方式,它們的使用方式基本一樣,這里以對(duì)象池為例介紹其使用方式,一般實(shí)現(xiàn)自己的對(duì)象池需要經(jīng)過個(gè)步驟實(shí)現(xiàn)接口該接口是一種工廠模式,實(shí)現(xiàn)其目的是讓對(duì)象池通過該工廠模式創(chuàng)建管理的對(duì)象創(chuàng)建對(duì)象池實(shí)例創(chuàng)建對(duì)象池我們假設(shè)對(duì)象是一 common-pool2 使用 common-pool2提供了3中對(duì)象池管理方式,它們的使用方式基本一樣,這里以GenericObjectPool對(duì)象...

    since1986 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<