元数据区

-XX:MetaspaceSize
-XX:MaxMetaspaceSize 该参数实际测试并不是设置最大元数据区大小,而是给了一个参考值,他会根据这个值动态调整元数据区的最大值

1
2
//查看jvm参数
jinfo -flag MetaspaceSize pid

1
2
//查看JVM参数的默认值
java -XX:+PrintFlagsFinal -version |grep JVMParamName

一些实验

1、采用以下参数,启动一个netty进程,5个连接,进行每秒100个消息的发送,内存保持在79M不变

1
2
3
4
-Xms60m
-Xmx60m
-XX:MetaspaceSize=20m
-XX:MaxMetaspaceSize=50m

2、然后在netty的客户端打断点,阻塞消息发送内存一直飙升 176M
3、放开断点保持消息接受通常,内存掉到144M
4、内存保持不变

问题:那么这些增加的内存到底占用在什么地方了?

初步怀疑是内存池,那么接下来准备采用非内存池的方式来做测试,看看链接断开完毕后内存会不会恢复正常..
接上,unpooled buffer也不释放

会不会测试内存太小,本身是jvm占用的,本次扩大内存到512M,看看增量
接上,内存依然会增加,当断点放开之后,内存涨到 700M。

试着使用-Dio.netty.maxDirectMemory = 0 参数,也是没有用的

关于-Dio.netty.maxDirectMemory参数

  • 小于0,不使用Cleaner 继承java的-XX:MaxDirectMemorySize参数,netty有自己的最大堆外内存够,也有自己的最大堆外内存,也就是说jvm实际最大堆外内存是2*MaxDirectMemorySize参数

  • 等于0,使用Cleaner,netty不会有自己的最大内堆外内存限制,而是和jdk一起享有一个最大内存 最大内存

  • 大于0,不使用Cleaner,netty就用自己定义的参数,和jdk无关,各自有格子的最大堆外内存

google-perftools分析

  1. 安装 gcc

    1
    yum install gcc gcc-c++ make
  2. 安装libunwind

    1
    2
    3
    4
    5
    6
    wget http://ftp.yzu.edu.tw/nongnu/libunwind/libunwind-1.1.tar.gz
    tar -xzvf libunwind-1.1.tar.gz
    cd libunwind-1.1
    ./configure
    make
    make install

2、安装google-perftools

1
2
3
4
5
6
7
8
wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.4/gperftools-2.4.tar.gz
tar -xzvf gperftools-2.4.tar.gz
cd gperftools-2.4
./configure
make
make install
在文件中/etc/ld.so.conf.d/usr_local_lib.conf 写入 /usr/local/lib
/sbin/ldconfig

修改java进程启动shell,其中之前
加入export LD_PRELOAD=/usr/local/lib/libtcmalloc.so
加入export HEAPPROFILE=/tmp/test (导出的文件放在哪里)
最终生成文件是在/tmp中, 也不知为何,就是在配置的上一级目录中

  1. 查看
    1
    pprof /usr/local/java/jdk1.8.0_152/bin/java ../mtest.0001.heap

此命令会进入一个程序
接下来使用top20查看使用20,就能看到使用内存的top20的点

top 显示内存使用情况,由高到低
gv 使用图形化表示
如果出现sh: dot: command not found 那么是没有安装图形工具
此时安装图形工具

1
yum install graphviz

web使用网站来查看

Top命令相关

/proc/$pid/stat 可以获取某进程的状态、

游戏消息分析

1
cat ../logs/game.log | grep '2019-09-07 15:36:16' | grep PerformanceManager | cut -d '[' -f 3

netty设置ByteBuf类型

利用ch.config().setAllocator或Bootstrap.option(ChannelOption.ALLOCATOR, ByteBufAllocator),
结合-Dio.netty.noUnsafe,可以灵活的在如下四种ByteBuf之间进行切换:

UnpooledHeapByteBuf

PooledHeapByteBuf

UnpooledDirectByteBuf

PooledDirectByteBuf