zoukankan      html  css  js  c++  java
  • netty的引用计数

    netty的引用计数文档看http://netty.io/wiki/reference-counted-objects.html

    为什么会引用引用计数呢,Java中不是有gc线程帮我们回收对象吗?我个人理解如下

    1:netty为了实现zero copy使用了Direct Buffer,该buffer从Native Memory分配出来,分配和回收效率要远低于在Java Heap上的对象,所以一般full gc来控制的,直接内存会自己检测情况而调用system.gc(),通过使用引用计数可以自己来控制该buffer的释放。具体看PlatformDependent.freeDirectBuffer(buffer)的实现。

    这块内容请看:http://blog.csdn.net/xieyuooo/article/details/7547435

    2:netty使用了Pooled的功能。有点像c++的对象池,先分配一大块内存,然后从里面切出一块一块的供你使用,引用计数为0放入pool中,供后面使用。

    如果不按按引用计数规则使用这两种对象,将会导致内存泄露。所以测试的时候需要测试下是有有内存泄漏。

    Netty引用计数的实现在AbstractReferenceCountedByteBuf代码里。

        private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater;
    
        static {
            AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> updater =
                    PlatformDependent.newAtomicIntegerFieldUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
            if (updater == null) {
                updater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
            }
            refCntUpdater = updater;
        }
    
        private volatile int refCnt = 1;

    volatile是线程可见变量,保存在Jvm的主内存中,而不是线程的工作内存里面。然后使用jdk的原子库对引用计数进行原子更新。
    AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUpdater通过反射原子更新对象的字段,被更新的字段是有要求的

    1:必须是volatile类型,
    2:注意访问描述符(public ,protected ,defualt,private).
    3: 只能是实例变量不能是类变量
    4:对于AtomicIntegerFieldUpdater和AtomicLongFieldUpdater只能修改int/long类型的字段,不能修改其包装类型(Integer/Long)。如果要修改包装类型就需要使用AtomicReferenceFieldUpdater

    public class Updater {
        public static void main(String[] args) throws InterruptedException {
            Container c=new Container();
              for(int i=0;i<1000;i++)
              {
                  Task t=new Task(c);
                  t.start();
                  t.join(); //join方法在start后调用,调用线程会等待被调用的线程执行完成后执行
    
              }
            System.out.println("============="+c.index);
        }
    }
    
    class Container{
        public volatile  int index=0;
    }
    
    class Task extends Thread {
        private AtomicIntegerFieldUpdater<Container> updater =
                AtomicIntegerFieldUpdater.newUpdater(Container.class,"index");
        private Container c;
    
        public Task(Container c) {
            this.c = c;
        }
        @Override
        public void run() {
            System.out.println(updater.getAndIncrement(c));
            System.out.println(updater.getAndDecrement(c));
        }
    }
  • 相关阅读:
    金额数字每隔3位用逗号区分
    tomcat结合shiro无文件webshell的技术研究以及检测方法
    python使用p12个人证书发送S/MIME加密,签名邮件
    CVE-2020-9484 tomcat session反序列化漏洞分析与复现
    Apache CommonCollection Gadget几种特殊的玩法
    weblogic t3协议回显穿透nat思路
    weblogic T3/iiop 回显分析
    ysoserial gadget之DNSURL gadget分析及实战利用
    CVE-2020-2555 weblogic 反序列化gadget 复现
    通达OA最新RCE漏洞分析
  • 原文地址:https://www.cnblogs.com/gaoxing/p/4249119.html
Copyright © 2011-2022 走看看