今天,发现游戏逻辑服务器内存溢出问题,每隔一定时间就生成java_pidxxxxxx.hprof ,基本1G内存分配不够用了,导致FGC频繁发生。
工具:
MAT Eclipse Memory Analyzer Tool(MAT)分析内存泄漏
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
2.为什么使用MAT?
当服务器应用占用了过多内存的时候,会遇到OutOfMemoryError。如何快速定位问题呢?Eclipse MAT的出现使这个问题变得非常简单。它能够离线分析dump的文件数据。
首页:http://www.eclipse.org/mat/
插件更新地址:
http://download.eclipse.org/mat/1.0/update-site/
排查原因:
1.是因为策划引入了一张大地图(2W*3W,),导致瞬间内存膨胀了160M,
2.热加载的时候地图系统内存占用会额外扩大n倍。
左:热加载前,右,热加载后
3.冗余属性数据存储
处理:
1.冗余属性数据存储:
把PathInfoConfig的_2xNodes和_4xNodes去掉,基本省下了一半的地图内存占用,
(左边,优化前,右边,优化后 看a部分)
2.停掉地图数据部分的热加载:
左边:热加载前,右边,热加载后,基本内存占用维持不变.
3.对PathNode的key 类型String换成 Integer,通过移位来生成key
x << 16|y
左边,优化前,右边,优化后,减少了40M左右
主要是hashmap的key的减少空间
优化前后做个对比
获取的堆栈分析文件
1.jmap -dump:format=b,file=/data/log/dump.dat 26822
2.通过JVM自动生成hprof 文件
4.PathNode的x和y 用short够用,value的值目前都为1用byte
发现内存占用都为32(25+7),没有上升的空间,所以这块不优化
JVM在分配内存时是以8 bytes为粒度进行分配
5.过滤掉只有在跨服服务器使用的地图
目前地图内存占用从400+降到了200+