欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

TThreadedSelectorServer 先 CAD加密 容及 Direct Memory OOM 阐明

点击: 次  来源:宝鼎软件 时间:2017-07-29

原文出处: 囚兔

一、TThreadedSelectorServer线程模子:

该处事会启动1个AcceptThread, 2个SelectorThread(默认为2个,可配置),一个woker线程池(池的巨细可配置),

TThreadedSelectorServer 先 CAD加密 容及 Direct Memory OOM 阐发

一个AcceptThread执行accept操纵,将accept到的Transport交给SelectorThread线程, AcceptThread中有个balance平衡器分派到SelectorThread;

SelectorThread执行read,write操纵,read到一个FrameBuffer(封装了要领名,参数,参数范例等数据,和读取写入,挪用要领的操纵)交给WorkerProcess线程池执行要领挪用。

二、SelectorThread中FrameBuffer读取的进程

每个SelectorThread线程利用FrameBuffer来读取数据。

org.apache.thrift.server.AbstractNonblockingServer.FrameBuffer:

 private boolean internalRead() {
      try {
        if (trans_.read(buffer_) < 0) {
          return false;
        }
        return true;
      } catch (IOException e) {
        LOGGER.warn("Got an IOException in internalRead!", e);
        return false;
      }
    }

代码中trans 为 TNonblockingSocket工具,

org.apache.thrift.transport.TNonblockingSocket:

 public int read(ByteBuffer buffer) throws IOException {
    return socketChannel_.read(buffer);
  }

实际上就是,从socketChannel中读取数据到FrameBuffer的buffer_ (堆内存) 变量中。

socketChannel的read要领中参数传的就是FrameBuffer的buffer_变量。

public int read(ByteBuffer var1)  // var1 即为FrameBuffer的buffer_变量

socketChannel在读取数据到FrameBuffer.buffer_的进程中,利用了sun.nio.ch.Util 和 sun.nio.ch.IOUtil 类来分派姑且的直接内存,来实现数据的读取。

sun.nio.ch.Util 类中持有一个线程内的环形缓存区,元素为分派的DirectByteBuffer,每次举办read和write时先从该缓存中拿DirectByteBuffer,条件是个中的DirectByteBuffer的size大于或便是需要的size。

假如没有满意条件的元素,图纸加密,则建设新的DirectByteBuffer,新的利用完后再放回环形缓存区,假如此时缓存区已满则,软件开发,则释放该DirectByteBuffer: 

sun.nio.ch.Util:

TThreadedSelectorServer 先 CAD加密 容及 Direct Memory OOM 阐发

小结:

Frame读取数据分两步: 先读取frame的size巨细,再读取整个frame的数据

  1. 读取frameSize(4个字节): 先分派4个字节的堆内存,然后从socketChannel中读取4个字节的数据,进程中从环形缓冲区中发生了或复用了一个字节长度大于便是4的直接内存。
  2. 读取整个frame数据: 先分派(4 + frameSize)巨细的堆内存,接着将frameSize(4个字节)这个int值放入分派的堆内存中,然后从socketChannel中读取一个字节长度为frameSize的数据,同样从socketChannel中读取,进程中从环形缓冲区中发生了或复用了一个字节长度大于便是frameSize的直接内存。

三、java.lang.OutOfMemoryError: Direct buffer memory 阐明

TThreadedSelectorServer 先 CAD加密 容及 Direct Memory OOM 阐发

监控阐明东西先容:

1. 调解JVM启动参数,如下:

-Dcom.sun.management.jmxremote.port=9988 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -XX:+PrintGC -XX:+HeapDumpBeforeFullGC -XX:+HeapDumpAfterFullGC

开启JMX处事,可实现长途通过jconsole.exe 和 jvisualvm.exe 来监控JVM的机能参数,个中jconsole可看到堆外内存的利用环境(利用了BufferPoolMXBean);

开启了JVM做full gc前后做一次dump操纵,用于阐明堆内存的利用。

2.别的利用Oracle官网上找到的MonBuffers 类来及时监控堆外内存的利用, 代码见附录;

3. Memory Analysis东西用于阐明dump文件;

4. tcpdump,wireshake别离用于捕捉和阐明Thrift处事吸收到的字节约。 

OOM问题阐明进程:

在监控的进程中,发明某个时间点堆外内存急剧上升到达1个多G,

TThreadedSelectorServer 先 CAD加密 容及 Direct Memory OOM 阐发

此时jvm做了一次full gc并做了dump操纵:

TThreadedSelectorServer 先 CAD加密 容及 Direct Memory OOM 阐发

用Memory Analysis 对 java_pid27220.hprof.2 dump文件举办阐明

TThreadedSelectorServer 先 CAD加密 容及 Direct Memory OOM 阐发