jvm内存溢出,求大神指导

做了一个物流的信息对接平台,从下级平台获取车辆的gps信息采用tcp 长连接,200辆车没30秒刷新一次数据,跑了2天jvm 溢出了就大神指导下则么解决,

 public class Serve {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap b = new ServerBootstrap(); // (2)
        b.group(bossGroup, workerGroup)
        //设置协议类型
            .channel(NioServerSocketChannel.class)
            //设置处理类
            .childHandler(new ChannelInitializer<SocketChannel>(){
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new ServeHandler());
                }           
            })
            .option(ChannelOption.SO_BACKLOG, 128)
            .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture f = b.bind(40009).sync();
            System.out.println("服务已启动");
            f.channel().closeFuture().sync();
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();

    }
 public class ServeHandler extends ChannelHandlerAdapter{
    HandlerExcutorPool excuPool=new HandlerExcutorPool(100, 500);  //新建线程池
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try{
            ByteBuf buf=(ByteBuf)msg;
            byte[] data=new byte[buf.readableBytes()];
            buf.readBytes(data);
            if(data[0]==0x5b&&data[data.length-1]==0x5d){
                byte[] content=new byte[data.length-2];
                content=common.subBytes(data, 1, data.length-2);
                byte[] relCon=EscapedUtil.Escaped(content);
                byte[] headAndBody=new byte[relCon.length-2];
                byte[] headArr=new byte[22];
                //抽出数据头和数据体
                for(int i=0;i<relCon.length-2;i++){
                    headAndBody[i]=(byte) (relCon[i]);
                    if(i<22){
                        headArr[i]=(byte) (relCon[i]);
                    }
                }
                //数据转义
                //headAndBody=EscapedUtil.Escaped(headAndBody);
                //crc校验
                int crc=GetCrc16_CCITT.GetCrc16_CCITT(headAndBody);
                //System.out.println(Integer.toHexString(crc));
                int crc1=(relCon[relCon.length-2]&0xff)<<8|(relCon[relCon.length-1]&0xff);
                if((crc&0xffff)==(crc1&0xffff)){
                    //得到数据头的bean
                    Head809 head=HeadService.get809Head(headAndBody);
                    //业务分发
                    if((head.getMsg_id()&0xffff)==MegId.UP_CONNECT_REQ){   //登入请求
                        LoginService login=new LoginService(headAndBody);
                        byte[] rebodyData=login.checkLogin(headAndBody,head.msg_gnsscenterid);  // 检查用户名密码和接入码
                        headArr[8]=0x10;
                        headArr[9]=0x02;
                        byte[] relData=common.getRelData(headArr, rebodyData);
                        //往客户端发送应答信息
                        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(relData));
                    }else if((head.getMsg_id()&0xffff)==MegId.UP_DISCONNECT_REQ){
                        headArr[8]=0x10;
                        headArr[9]=0x04;
                        byte[] relData=common.getRelData(headArr);
                        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(relData)).addListener(ChannelFutureListener.CLOSE);
                    }else if((head.getMsg_id()&0xffff)==MegId.UP_LINKTEST_REQ){
                        headArr[8]=0x10;
                        headArr[9]=0x06;
                        byte[] relData=common.getRelData(headArr);
                        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(relData));
                    }else if((head.getMsg_id()&0xffff)==MegId.UP_EXG_MSG){
                        excuPool.executor(new PositionService(headAndBody));  // 线程池

                    }
                }       
            }
            System.gc();
        }finally {
            ReferenceCountUtil.release(msg);
        }

    }

 public class HandlerExcutorPool {
    private ExecutorService excutor;
    public HandlerExcutorPool(int maxPoolSize,int queueSize){
        this.excutor=new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors(),
                maxPoolSize,
                120L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(queueSize));   
    }
    public void executor(Runnable task){
        this.excutor.execute(task);
    }
}
 public class PositionService implements Runnable {
    //public static HashMap<String, String> carMap=new HashMap<String, String>();
    private byte[] arr;
    public PositionService(byte[] data){
        this.arr=data;
    }
    private CarPositionInfo positionHandler(byte[] data) throws UnsupportedEncodingException{
        byte[] body=common.subBytes(data, 22, data.length-22);
        byte[] carId=common.subBytes(body, 0, 21);
        byte[] type=common.subBytes(body, 22, 2);
        byte[] lastLength=common.subBytes(body, 24, 4);
        long leng=(((lastLength[0]&0xff)<<24)|((lastLength[1]&0xff)<<16)|((lastLength[2]&0xff)<<8)|(lastLength[3]&0xff))&0x00000000ffffffff;
        byte[] last=common.subBytes(body, 28,36);
        String carNum=new String(carId, "GBK");
        int subType=(((type[0]&0xff)<<8)|(type[1]&0xff))&0x0000ffff;
        CarPositionInfo posiInfo=new CarPositionInfo();
        posiInfo.setCarId(carNum);
        if(subType==MegId.UP_EXG_MSG_REAL_LOCATION){
            boolean entrpt=last[0]==0x00?false:true;
            int year=(((last[3]&0xff)<<8)|(last[4]&0xff))&0x0000ffff;
            short month=(short) (last[2]&0x00ff);
            short day=(short) (last[1]&0x00ff);
            short hour=(short) (last[5]&0x00ff);
            short min=(short) (last[6]&0x00ff);
            short sec=(short) (last[7]&0x00ff);
            String date=""+year+"-"+month+"-"+day+" "+hour+":"+min+":"+sec;
            long lon=(((last[8]&0xff)<<24)|((last[9]&0xff)<<16)|((last[10]&0xff)<<8)|(last[11]&0xff))&0x00000000ffffffff;
            long lat=(((last[12]&0xff)<<24)|((last[13]&0xff)<<16)|((last[14]&0xff)<<8)|(last[15]&0xff))&0x00000000ffffffff;
            String lonStr=""+lon/1000000+"."+getStr(""+lon%1000000,6);
            String latStr=""+lat/1000000+"."+getStr(""+lat%1000000,6);
            int vec=(((last[16]&0xff)<<8)|(last[17]&0xff))&0x0000ffff;
            posiInfo.setEncrypt(entrpt);
            posiInfo.setDate(date);
            posiInfo.setLon(Double.valueOf(lonStr));
            posiInfo.setLat(Double.valueOf(latStr));
            posiInfo.setVec(vec);
        }

        return posiInfo;
    }
    public void sendMsg(byte[] data) {
        try{
            CarPositionInfo carInfo=positionHandler(data);
            HttpRequestUtils req=new HttpRequestUtils();
            Map map=req.getparams();
            SimpleDateFormat simp=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            map.put("entity_name", carInfo.carId.trim().replaceAll(" +", ""));
            map.put("latitude", carInfo.lat);
            map.put("longitude", carInfo.lon);
            map.put("speed", carInfo.vec);
            map.put("coord_type", carInfo.encrypt?2:1);
            map.put("loc_time", (simp.parse(carInfo.date).getTime())/1000);
            String json=req.httpPostRequest("http://api.map.baidu.com/trace/v2/track/addpoint", map);
            }catch (Exception e) {
                e.printStackTrace();
        }
    }
    private String getStr(String a,int b){
        String str="";
        if(a.length()>=b)
            return a;
        else{
            for(int i=a.length();i<b;i++){
                str+="0";
            }
            return str+a;
        }

    }
    public void run() {
        try {
            sendMsg(this.arr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

主要跑的ServeHandler中的excuPool.executor(new PositionService(headAndBody)); 这段代码跑了2天jvm内存溢出求解则么玩图片说明

是不是创建线程消耗了了太多的native memory资源,; JDk安装目录、bin文件夹下,运行jconsole.exe,看一下线程相关信息。

HandlerExcutorPool excuPool=new HandlerExcutorPool(100, 500); //新建线程池
--- 这里100是不是没必要这么大,有个10就差不多了