[netty5: LifecycleTracer & ResourceSupport]-源码分析

LifecycleTracer

java 复制代码
@UnstableApi
public abstract class LifecycleTracer {
	// 默认关闭
    static final boolean lifecycleTracingEnabled = SystemPropertyUtil.getBoolean("io.netty5.buffer.lifecycleTracingEnabled", false);

	// 重点!
    public static LifecycleTracer get() {
    	// 生命周期追踪未启用 且 泄漏检测关闭
        if (!lifecycleTracingEnabled && LeakDetection.leakDetectionEnabled == 0) {
            return NoOpTracer.INSTANCE;
        }
        return new StackTracer();
    }

    public abstract void allocate();
    
    public abstract void acquire(int acquires);

    public abstract void drop(int acquires);

    public abstract void close(int acquires);

    public abstract void touch(Object hint);
    
    public abstract <I extends Resource<I>, T extends ResourceSupport<I, T>> Owned<T> send(Owned<T> instance);

    public abstract void splitTo(LifecycleTracer splitTracer);

    public abstract <E extends Throwable> E attachTrace(E throwable);
    
    public abstract Collection<TracePoint> collectTraces();

	// NoOpTracer
	
	// StackTracer, Trace, Traceback

	// TraceType 
	// AttachmentType 
}

TraceType

用于记录资源生命周期中发生的关键事件。

枚举值 含义
ALLOCATE 分配资源(如内存)时发生的事件。
ACQUIRE 从池中获取(重用)资源的事件。
CLOSE 显式关闭资源的事件。
DROP 底层释放资源(drop 操作)。
SEND 资源被发送的事件(如跨线程)。
RECEIVE 资源被接收的事件。
TOUCH 调用 touch(Object hint) 时记录的事件。用于定位资源流向。
SPLIT 缓冲区被拆分为子缓冲区的事件。
java 复制代码
private enum TraceType {
    ALLOCATE,
    ACQUIRE,
    CLOSE,
    DROP,
    SEND,
    RECEIVE,
    TOUCH,
    SPLIT,
}

AttachmentType

用于连接不同资源之间的因果或传递关系。

枚举值 含义
SEND_FROM 表示当前追踪器是被"发送自"哪个追踪器。
RECEIVED_AT 表示当前追踪器"接收到"哪个资源。
SPLIT_FROM 当前追踪器是从哪个对象拆分来的。
SPLIT_TO 当前追踪器拆分出去形成了哪个对象。
HINT 来源于 touch(hint) 中的 hint 参数。
java 复制代码
private enum AttachmentType {
    SEND_FROM,
    RECEIVED_AT,
    SPLIT_FROM,
    SPLIT_TO,
    HINT,
}

ResourceSupport

提供对资源生命周期追踪的支持,主要通过 LifecycleTracer 进行资源的生命周期管理。它是一个基础类,可以为所有继承它的资源类型提供生命周期追踪功能。

java 复制代码
@UnstableApi
public abstract class ResourceSupport<I extends Resource<I>, T extends ResourceSupport<I, T>> implements Resource<I> {

    private int acquires; // Closed if negative.
    private Drop<T> drop;
    private final LifecycleTracer tracer;

    protected ResourceSupport(Drop<T> drop) {
        this.drop = drop;
        tracer = LifecycleTracer.get();
        tracer.allocate();
    }

    @SuppressWarnings("unchecked")
    static <T> T acquire(ResourceSupport<?, ?> obj) {
        return (T) obj.acquire();
    }
    
    static LifecycleTracer getTracer(ResourceSupport<?, ?> obj) {
        return obj.tracer;
    }

    protected final T acquire() {
        if (acquires < 0) {
            throw attachTrace(createResourceClosedException());
        }
        if (acquires == Integer.MAX_VALUE) {
            throw new IllegalStateException("Reached maximum allowed acquires (" + Integer.MAX_VALUE + ").");
        }
        acquires++;
        tracer.acquire(acquires);
        return impl();
    }

    protected abstract RuntimeException createResourceClosedException();
    
    @Override
    public final void close() {
        if (acquires == -1) {
            throw attachTrace(new IllegalStateException("Double-free: Resource already closed and dropped."));
        }
        int acq = acquires;
        acquires--;
        if (acq != 0) {
            // Only record a CLOSE if we're not going to record a DROP.
            tracer.close(acq);
        } else {
            // The 'acquires' was 0, now decremented to -1, which means we need to drop.
            tracer.drop(0);
            try {
                drop.drop(impl());
                Reference.reachabilityFence(this); // Avoid racing with any Cleaner.
            } finally {
                makeInaccessible();
            }
        }
    }

    @Override
    public final Send<I> send() {
        if (acquires < 0) {
            throw attachTrace(createResourceClosedException());
        }
        if (!isOwned()) {
            throw notSendableException();
        }
        try {
            var owned = tracer.send(prepareSend());
            return new SendFromOwned<>(owned, drop, getClass());
        } finally {
            acquires = -2; // Close without dropping. This also ignore future double-free attempts.
            makeInaccessible();
        }
    }

    protected <E extends Throwable> E attachTrace(E throwable) {
        return tracer.attachTrace(throwable);
    }

    protected IllegalStateException notSendableException() {
        return new IllegalStateException("Cannot send() a reference counted object with " + countBorrows() + " borrows: " + this + '.');
    }

    static boolean isOwned(ResourceSupport<?, ?> obj) {
        return obj.isOwned();
    }

    protected boolean isOwned() {
        return acquires == 0;
    }

    static int countBorrows(ResourceSupport<?, ?> obj) {
        return obj.countBorrows();
    }

    protected int countBorrows() {
        return Math.max(acquires, 0);
    }

    @Override
    public boolean isAccessible() {
        return acquires >= 0;
    }

    @Override
    public I touch(Object hint) {
        if (isAccessible()) {
            tracer.touch(hint);
        }
        return self();
    }

    protected abstract Owned<T> prepareSend();

    protected void makeInaccessible() {
    }

    protected Drop<T> unsafeGetDrop() {
        return drop;
    }

    protected void unsafeSetDrop(Drop<T> replacement) {
        drop = Objects.requireNonNull(replacement, "Replacement drop cannot be null.");
    }

    @SuppressWarnings("unchecked")
    private I self() {
        return (I) this;
    }

    @SuppressWarnings("unchecked")
    private T impl() {
        return (T) this;
    }
}

AdaptableBuffer

AdaptableBuffer 继承自 ResourceSupport,因此它和它的子类(UnsafeBufferNioBufferMemSegBuffer)能够利用 ResourceSupport 提供的资源生命周期追踪功能。

java 复制代码
public abstract class AdaptableBuffer<T extends ResourceSupport<Buffer, T>> extends ResourceSupport<Buffer, T> implements Buffer {

    protected final AllocatorControl control;

    protected AdaptableBuffer(Drop<T> drop, AllocatorControl control) {
        super(drop);
        this.control = control;
    }

    @Override
    public AdaptableBuffer<T> touch(Object hint) {
        super.touch(hint);
        return this;
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof Buffer && InternalBufferUtils.equals(this, (Buffer) o);
    }

    @Override
    public int hashCode() {
        return InternalBufferUtils.hashCode(this);
    }
}
相关推荐
daidaidaiyu2 天前
一文学习和实践 当下互联网安全的基石 - TLS 和 SSL
java·netty
enjoy编程2 天前
Spring boot 4 探究netty的关键知识点
spring boot·设计模式·reactor·netty·多线程
ps酷教程5 天前
HttpData
http·netty
ps酷教程10 天前
ChunkedWriteHandler源码浅析
java·netty·分块传输
奕辰杰13 天前
Netty私人学习笔记
笔记·学习·netty·网络通信·nio
ps酷教程15 天前
HttpObjectDecoder源码浅析
java·netty·httpaggregator
魔芋红茶20 天前
Netty 简易指南
java·开发语言·netty
ps酷教程20 天前
HttpAggregator源码浅析
netty·httpaggregator
9527出列23 天前
Netty实战--使用netty构建WebSocket服务
websocket·网络协议·netty