X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fio%2FLeakTrackingByteBufferPool.java;h=f9ac66e7259f54b777015086fd85e36bd4b5369d;hp=a6fc7562d2e750982d49ed89e04e95f0d6d5c56f;hb=ba4f228fa9f72d50991a2218cfd83987ef5d385e;hpb=875b5e9651498a0cd8e0001c0742ba843e47cad0 diff --git a/lib/jetty/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java b/lib/jetty/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java index a6fc7562..f9ac66e7 100644 --- a/lib/jetty/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java +++ b/lib/jetty/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -19,7 +19,9 @@ package org.eclipse.jetty.io; import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicLong; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.LeakDetector; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.log.Log; @@ -31,14 +33,24 @@ public class LeakTrackingByteBufferPool extends ContainerLifeCycle implements By private final LeakDetector leakDetector = new LeakDetector() { + public String id(ByteBuffer resource) + { + return BufferUtil.toIDString(resource); + } + @Override protected void leaked(LeakInfo leakInfo) { + leaked.incrementAndGet(); LeakTrackingByteBufferPool.this.leaked(leakInfo); } }; - + + private final static boolean NOISY = Boolean.getBoolean(LeakTrackingByteBufferPool.class.getName() + ".NOISY"); private final ByteBufferPool delegate; + private final AtomicLong leakedReleases = new AtomicLong(0); + private final AtomicLong leakedAcquires = new AtomicLong(0); + private final AtomicLong leaked = new AtomicLong(0); public LeakTrackingByteBufferPool(ByteBufferPool delegate) { @@ -51,8 +63,13 @@ public class LeakTrackingByteBufferPool extends ContainerLifeCycle implements By public ByteBuffer acquire(int size, boolean direct) { ByteBuffer buffer = delegate.acquire(size, direct); - if (!leakDetector.acquired(buffer)) - LOG.warn("ByteBuffer {}@{} not tracked", buffer, System.identityHashCode(buffer)); + boolean leaked = leakDetector.acquired(buffer); + if (NOISY || !leaked) + { + leakedAcquires.incrementAndGet(); + LOG.info(String.format("ByteBuffer acquire %s leaked.acquired=%s", leakDetector.id(buffer), leaked ? "normal" : "LEAK"), + new Throwable("LeakStack.Acquire")); + } return buffer; } @@ -61,11 +78,46 @@ public class LeakTrackingByteBufferPool extends ContainerLifeCycle implements By { if (buffer == null) return; - if (!leakDetector.released(buffer)) - LOG.warn("ByteBuffer {}@{} released but not acquired", buffer, System.identityHashCode(buffer)); + boolean leaked = leakDetector.released(buffer); + if (NOISY || !leaked) + { + leakedReleases.incrementAndGet(); + LOG.info(String.format("ByteBuffer release %s leaked.released=%s", leakDetector.id(buffer), leaked ? "normal" : "LEAK"), new Throwable( + "LeakStack.Release")); + } delegate.release(buffer); } + public void clearTracking() + { + leakedAcquires.set(0); + leakedReleases.set(0); + } + + /** + * @return count of BufferPool.acquire() calls that detected a leak + */ + public long getLeakedAcquires() + { + return leakedAcquires.get(); + } + + /** + * @return count of BufferPool.release() calls that detected a leak + */ + public long getLeakedReleases() + { + return leakedReleases.get(); + } + + /** + * @return count of resources that were acquired but not released + */ + public long getLeakedResources() + { + return leaked.get(); + } + protected void leaked(LeakDetector.LeakInfo leakInfo) { LOG.warn("ByteBuffer " + leakInfo.getResourceDescription() + " leaked at:", leakInfo.getStackFrames());