首页 > 系统相关 >JVM内存溢出深度分析

JVM内存溢出深度分析

时间:2022-12-27 19:39:14浏览次数:60  
标签:MAT 占用 地图 内存 JVM 优化 溢出 加载



今天,发现游戏逻辑服务器内存溢出问题,每隔一定时间就生成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倍。

左:热加载前,右,热加载后

JVM内存溢出深度分析_热加载

3.冗余属性数据存储

处理:

1.冗余属性数据存储:

把PathInfoConfig的_2xNodes和_4xNodes去掉,基本省下了一半的地图内存占用,

(左边,优化前,右边,优化后 看a部分)

JVM内存溢出深度分析_Memory_02

2.停掉地图数据部分的热加载:

左边:热加载前,右边,热加载后,基本内存占用维持不变.

JVM内存溢出深度分析_Memory_03

3.对PathNode的key 类型String换成 Integer,通过移位来生成key 
x << 16|y 

左边,优化前,右边,优化后,减少了40M左右

            主要是hashmap的key的减少空间

JVM内存溢出深度分析_内存泄漏_04



优化前后做个对比 

获取的堆栈分析文件

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+



参考文章:​​Shallow heap & Retained heap​


​Java对象内存结构 ​

标签:MAT,占用,地图,内存,JVM,优化,溢出,加载
From: https://blog.51cto.com/u_4176761/5973410

相关文章

  • 高并发下Netty4底层bug导致直接内存溢出分析
    事故记录:10点游戏开服,迅速冲破2300+单区同时在线18点15分,运营反应玩家进不了,准备吃饭的人被抓回来排查故障发现,由于直接内存被占满,一直在FullGC,并且回收不掉,所以完全不......
  • linux下的内存查看(virt,res,shr,data的意义)
    其实在认真阅读了这篇名为“​​计算内存使用​​​”的文章之后,还是处于半迷糊状态。这位作者就说Linux下面没有特别好的显示内存占用的工具,虽然有top和free,但都说得不清楚......
  • JDK8引进的JVM参数变化记录
    1.PermGen空间​​被移除了,取而代之的是Metaspace​​需要做的调整为-XX:PermSize=64m-XX:MaxPermSize=128m变成 -XX:MetaspaceSize=64m-XX:MaxMetaspaceSize=128m否则......
  • JVM日志分析及工具
    JVM的GC日志的主要参数包括如下几个:-XX:+PrintGC输出GC日志-XX:+PrintGCDetails输出GC的详细日志-XX:+PrintGCTimeStamps输出GC的时间戳(以基准时间的形式)-XX:+Print......
  • JVM CMS GC算法解析
    CMS,全称ConcurrentLowPauseCollector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求大于对吞吐量的要求......
  • JVM疑难启动参数汇总
    ThreadLocalAllocationBuffer,简称就是:TLAB,即内存本地的持有的buffer,设置参数有:-XX:+UseTLAB                         启用这种机制的意思-XX......
  • Arthas 查询服务器内存数据
    1、打开Arthas所在位置eg:/home2、java-jararthas-boot.jar运行jar包3、选择要执行的javajar包eg:14、执行查看命令vmtool--actiongetInstances--classNameco......
  • 【C语言】memcpy() 内存拷贝不重叠
    前言本篇博客就来介绍下关于C语言常用的内存函数之memcpy()函数。 ......
  • SetProcessWorkingSetSize减少内存占用?啥也不是
    结论:别用这个函数,他会把内存写不下的写到硬盘的虚拟内存中去(注:硬盘中的虚拟内存默认在系统盘里)贴一段博客园名称pdfw的代码点击查看代码[System.Runtime.InteropServ......
  • [C++] C++中关于内存的初解
    内存四区1.代码区存放函数体的二进制代码,由操作系统进行管理。代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码就可以。代码是只读的,只读的......