Skip to content

[Potential Issue] Make sure no resource leak here #527

@NickNYU

Description

@NickNYU

@LanternLee 最近在整理JVM的GC和锁机制问题,顺便复习下x-pipe中keeper的锁用法,看到这个地方可能存在有泄漏的问题(我不是很确定, 需要验证一下, 我最近事情比较多, 只能提个issue, 你们帮忙看一下了),父类里面的deallocate是这么写的

@Override
    protected void deallocate() {
        FileChannel file = this.file;

        if (file == null) {
            return;
        }
        this.file = null;

        try {
            file.close();
        } catch (IOException e) {
            if (logger.isWarnEnabled()) {
                logger.warn("Failed to close a file.", e);
            }
        }
    }

这个file不是File类,而是一个file channel,在netty写出去之后,会调用 release 方法,在 io.netty.util.AbstractReferenceCounted 中,里面其实调用的就是dealloc的方法:

@Override
    public boolean release() {
        return release0(1);
    }

    @Override
    public boolean release(int decrement) {
        return release0(checkPositive(decrement, "decrement"));
    }

    private boolean release0(int decrement) {
        int oldRef = refCntUpdater.getAndAdd(this, -decrement);
        if (oldRef == decrement) {
            deallocate();
            return true;
        } else if (oldRef < decrement || oldRef - decrement > oldRef) {
            // Ensure we don't over-release, and avoid underflow.
            refCntUpdater.getAndAdd(this, decrement);
            throw new IllegalReferenceCountException(oldRef, -decrement);
        }
        return false;
    }

回头看这个地方,filechannel在通过netty的channel写给下游的slave之后,只是看看是否关闭了 private ControllableFile file;,而可能漏掉了FileChannel (FileChannel 从对象关系来说,是从ControllableFile这个父亲中,分出来的child)
在Linux的模型下,相当于父子进程, 父进程被关闭, 子进程没有关闭, 从而可能成为 僵尸进程或者是孤儿进程(这个知识点我不是很确定)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions