java.lang.Error: Maximum permit count exceeded on SingleThreadExecutor

java.lang.Error: Maximum permit count exceeded on SingleThreadExecutor

在高流量时抛出以下异常,我不确定原因:

PcapHelper failed reading packet: packet: java.lang.Error: Maximum permit count exceeded(Maximum permit count exceeded) -> ST:
java.util.concurrent.Semaphore$Sync.tryReleaseShared(Semaphore.java:192) -> java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1341) ->
java.util.concurrent.Semaphore.release(Semaphore.java:609) -> org.jnetpcap.nio.DisposableGC.dispose(Unknown Source) -> org.jnetpcap.nio.DisposableGC.drainRefQueueBounded(Unknown Source)
 -> org.jnetpcap.nio.DisposableReference.<init>(Unknown Source) -> org.jnetpcap.nio.JMemoryReference.<init>(Unknown Source) -> org.jnetpcap.nio.JMemory.createReference(Unknown Source) -
> org.jnetpcap.nio.JMemory.allocate(Unknown Source) -> org.jnetpcap.nio.JMemory.<init>(Unknown Source) -> org.jnetpcap.nio.JMemoryPool$Block.<init>(Unknown Source) -> org.jnetpcap.nio.J
MemoryPool.newBlock(Unknown Source) -> org.jnetpcap.nio.JMemoryPool.getBlock(Unknown Source) -> org.jnetpcap.nio.JMemoryPool.duplicate2(Unknown Source) -> org.jnetpcap.packet.PcapPacket
.transferHeaderAndDataFrom0(Unknown Source) -> org.jnetpcap.packet.PcapPacket.<init>(Unknown Source) -> com.topspin.intguard.utils.PcapHelper.lambda$getPacket[=10=](PcapHelper.java:199) -> java.util.concurrent.FutureTask.run(FutureTask.java:266) -> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) -> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) -> java.lang.Thread.run(Thread.java:748) ->

引发异常的代码:

public static IPcapPacket getPacket(Pcap pcap, PcapHeader hdr, JBuffer buf, boolean isFirstPacket,
        String interfaceName) throws InterruptedException, ExecutionException {
    Future<IPcapPacket> result = null;
    if (!SniffingService.isInProcess || isFirstPacket) {
        result = sniffingExecutorService.submit(() -> {
        PcapPacket pcapPacket = null;
        try {
            Log.Parsing.trace("{} getting packet for interface: {}", PcapHelper.class.getSimpleName(),
                interfaceName);
            if (pcap != null && pcap.nextEx(hdr, buf) == Pcap.NEXT_EX_OK) {
            pcapPacket = new PcapPacket(hdr, buf);
            }
            if (isFirstPacket) {
            Thread.sleep(500);
            }
            return getIPcapPacket(pcapPacket, interfaceName);
        } catch (Throwable e) {
            Log.Parsing.error("{} failed reading packet: packet: {}", PcapHelper.class.getSimpleName(),
                ExceptionUtils.stackTraceToString(e));
            if (pcapPacket != null) {
            Log.Parsing.error("{} packet: {}", PcapHelper.class.getSimpleName(), pcapPacket.toString());
            }
            return null;
        }
        });
    }
    return result != null ? result.get() : null;
    }

我想这与期货没有按时装扮有关,但我不能真正指出问题所在。

我做了以下更改,问题已解决:

public static IPcapPacket getPacket(Pcap pcap, PcapHeader hdr, JBuffer buf, boolean isFirstPacket,
        String interfaceName) throws InterruptedException, ExecutionException {
    Future<IPcapPacket> future = null;
    if (!SniffingService.isInProcess || isFirstPacket) {
        future = sniffingExecutorService.submit(() -> {
        PcapPacket pcapPacket = null;
        try {
            Log.Parsing.trace("{} getting packet for interface: {}", PcapHelper.class.getSimpleName(),
                interfaceName);
            if (pcap != null && pcap.nextEx(hdr, buf) == Pcap.NEXT_EX_OK) {
            pcapPacket = new PcapPacket(hdr, buf);
            }
            if (isFirstPacket) {
            Thread.sleep(500);
            }
            return getIPcapPacket(pcapPacket, interfaceName);
        } catch (Throwable e) {
            Log.Parsing.error("{} failed reading packet: packet: {}", PcapHelper.class.getSimpleName(),
                ExceptionUtils.stackTraceToString(e));
            if (pcapPacket != null) {
            Log.Parsing.error("{} packet: {}", PcapHelper.class.getSimpleName(), pcapPacket.toString());
            }
            return null;
        }
        });
    }

    IPcapPacket result = (future != null ? future.get() : null);
    future = null;
    return result;
    }

将 future 更改为 null,问题就解决了。垃圾收集器知道这个未来已经完成并收集它。