• 关于sum.misc.Unsafe的一点记录


    最近在读Undertow的源码,对于ServletPrintWriterDelegate类的实现比较感兴趣,做个记录。

    源码github坐标:ServletPrintWriterDelegate.java

    该类继承的是PrintWriter,但是由于并不实用PrintWriter中的OutputStream,所以实用Unsafe.allocateInstance构造了一个newInstance,完美的绕过了父类的构造方法,并可用于所有适用接口。

    做个记录,备忘。

    生成实例:

    public static ServletPrintWriterDelegate newInstance(final ServletPrintWriter servletPrintWriter) {
        final ServletPrintWriterDelegate delegate;
        if (System.getSecurityManager() == null) {
            try {
                delegate = (ServletPrintWriterDelegate) UNSAFE.allocateInstance(ServletPrintWriterDelegate.class);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            }
        } else {
            delegate = AccessController.doPrivileged(new PrivilegedAction<ServletPrintWriterDelegate>() {
                @Override
                public ServletPrintWriterDelegate run() {
                    try {
                        return  (ServletPrintWriterDelegate) UNSAFE.allocateInstance(ServletPrintWriterDelegate.class);
                    } catch (InstantiationException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        delegate.setServletPrintWriter(servletPrintWriter);
        return delegate;
    }

    获取Unsafe:

    private static Unsafe getUnsafe() {
        if (System.getSecurityManager() != null) {
            return AccessController.doPrivileged(new PrivilegedAction<Unsafe>() {
                public Unsafe run() {
                    return getUnsafe0();
                }
            });
        }
        return getUnsafe0();
    }
    
    private static Unsafe getUnsafe0()  {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            return (Unsafe) theUnsafe.get(null);
        } catch (Throwable t) {
            throw new RuntimeException("JDK did not allow accessing unsafe", t);
        }
    }

    关于Unsafe进行了简单的查看,除了用于绕过jvm生成对象之外,该类还提供了非常多的基于底层的操作,请参见:

    sun.misc.Unsafe的理解

    读完之后有几个问题尚未深究,回头考虑补充:

    1、是否可以在一定程度上,使用该类去替代一些反射的调用。

    2、据说Unsafe的操作,是会绕过jvm的GC的,那如同上文那样的操作,allocateInstance出来的对象,是否需要手动释放?

    检查了下,通过allocateInstance生成的对象,内存空间属于Java Heap,会被gc,不需要也不可以进行手动释放。

  • 相关阅读:
    Func,Action 的介绍及其用法
    创建自定义Windows phone 样式(二)mango下的实现
    今天五一休息
    关于地震
    第一步
    心绪不佳
    真的无语
    购物,生活
    一周结束
    who怕who
  • 原文地址:https://www.cnblogs.com/rayz/p/8758952.html
Copyright © 2020-2023  润新知