当前位置: 首页 > 工具软件 > open-selector > 使用案例 >

Netty源码分析 NioEventLoop的openSelector性能优化

宋明亮
2023-12-01

DISABLE_KEYSET_OPTIMIZATION: 判断是否需要对sun.nio.ch.SelectorImpl中的selectedKeys进行优化, 不做配置的话默认需要优化,主要优化在哪?

Netty通过反射将selectedKeySet与sun.nio.ch.SelectorImpl中的两个field selectedKeys和publicSelectedKeys绑定,
大家知道SelectorImpl原来的selectedKeys和publicSelectedKeys数据结构是HashSet,而HashSet的数据结构是数组+链表,
新的数据结构是由2个数组A、B组成,初始大小是1024,避免了HashSet扩容带来的性能问题。除了扩容外,遍历效率也是一个原因,对于需要遍历selectedKeys的全部元素, 数组效率无疑是最高的。

 

//获取selector,并对其进行优化
private SelectorTuple openSelector() {
        final Selector unwrappedSelector;
        try {
            //创建java原生selector
            unwrappedSelector = provider.openSelector();
        } catch (IOException e) {
            throw new ChannelException("failed to open a new selector", e);
        }

        //是否需要优化,默认需要DISABLE_KEYSET_OPTIMIZATION=false
        if (DISABLE_KEYSET_OPTIMIZATION) {
            return new SelectorTuple(unwrappedSelector);
        }

        //尝试获取sun.nio.ch.SelectorImpl的class对象
        Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                    return Class.forName(
                            "sun.nio.ch.SelectorImpl",
                            false,
                            PlatformDependent.getSystemClassLoader());
                } catch (Throwable cause) {
                    return cause;
                }
            }
        });

        //如果返回maybeSelectorImplClass不是一个class对象,或者maybeSelectorImplClass不是(unwrappedSelector.getClass()他的子类。
        if (!(maybeSelectorImplClass instanceof Class) ||
                // ensure the current selector implementation is what we can instrument.
                !((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) {

            //如果是异常说明上面方法抛出异常
            if (maybeSelectorImplClass instanceof Throwable) {
                Throwable t = (Throwable) maybeSelectorImplClass;
                logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, t);
            }
            //创建一个SelectorTuple,内部unwrappedSelector并没有被优化
            return new SelectorTuple(unwrappedSelector);
        }

        //selector的class对象
        final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
        //内部素组结构实现的set接口
        final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();

        Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                    //反射获取属性
                    Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
                    Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");

                    //设置属性可访问
                    Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }

                    //设置属性可访问
                    cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }

                    //把原来属性设置为selectedKeySet(它是素组实现),原来是hashmap实现
                    selectedKeysField.set(unwrappedSelector, selectedKeySet);
                    publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
                    return null;
                } catch (NoSuchFieldException e) {
                    return e;
                } catch (IllegalAccessException e) {
                    return e;
                }
            }
        });

        //如果返回结果是异常信息
        if (maybeException instanceof Exception) {
            selectedKeys = null;
            Exception e = (Exception) maybeException;
            logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, e);
            //返回SelectorTuple,内部unwrappedSelector并没有被优化
            return new SelectorTuple(unwrappedSelector);
        }

        //赋值
        selectedKeys = selectedKeySet;
        logger.trace("instrumented a special java.util.Set into: {}", unwrappedSelector);

        //unwrappedSelector内部的selectedKeys和publicSelectedKeys俩个数据结构已用素组优化
        //SelectedSelectionKeySetSelector包装了unwrappedSelector和selectedKeySet
        return new SelectorTuple(unwrappedSelector,
                                 new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));
}

 

 类似资料: