java image 内存不足_一招解决游戏内存不足的神器Caffeine
问题定位:
最近奉命解决游戏中一直在的内存不够的问题,最终定位到底层的缓存机制使用的是google提供的ConcurrentLinkedHashMap做数据缓存的。
简单介绍下ConcurrentLinkedHashMap,这是一个基于LRU策略的缓存,说白了就是热点数据缓存,支持设置最大缓存个数,监控到缓存数量超过最大值后会依据权重策略让数据过期。
分析:
根据ConcurrentLinkedHashMap的特性,我们这边推测出玩家数据在被加载放到缓存后,如果缓存没有超过设置的最大值,则这些数据会一直放在缓存中;合理上来说这些没被使用的数据,在空闲一定时间后是可以被清除的,而不用一直占据在缓存中。
然而ConcurrentLinkedHashMap并没有在数据空闲一定时间后自动清空数据的机制,因而想要解决这个缓存问题,必须使用一个既支持基于缓存个数大小回收,又支持基于空闲时间回收的第三方组件,而在多番了解和数据查证后最终选择了Caffeine。
Caffeine是什么
Caffeine 是一个高性能的 Java 缓存库,缓存和 Map 之间的一个根本区别在于缓存可以根据回收策略回收存储的数据。此策略直接影响缓存的命中率 ,而缓存命中率额也是缓存库的一个重要特征。Caffeine 因使用 Window TinyLfu 回收策略,提供了一个近乎最佳的命中率。
我们可以看到官网提供的几张性能截图
场景1:8个线程读,100%的读操作
image-20201101101125396
场景二:6个线程读,2个线程写,也就是75%的读操作,25%的写操作
image-20201101101157144
场景三:8个线程写,100%的写操作
image-20201101101219341
可以清楚的看到Caffeine效率明显的高于其他缓存。
将Caffeine替换掉ConcurrentLinkedHashMap,接下来就是要验证下,是否支持基于空闲时间回收,进而解决我们游戏中的内存问题了。
Caffeine和ConcurrentLinkedHashMap的使用对比
操作流程:本地起两个服,一个缓存底层使用的是ConcurrentLinkedHashMap,另一个底层使用的是Caffeine,Caffeine服设置的数据操作空闲时间是1分钟,起服后分别使用jvisualvm记录起始内存曲线,截图保留,之后启动2000个机器人模拟登陆,登陆后再过1分钟分别手动调用FullGC,查看jvisualvm记录的内存曲线,并查看堆dump记录。
【ConcurrentLinkedHashMap服】起始内存
image-20201101103752470
【ConcurrentLinkedHashMap服】2000个机器人模拟登陆后下线,并手动调用FullGC后查看内存曲线
image-20201101104016330
我们可以看到堆内存并没有回到原来的曲线。
查看堆dump记录
image-20201101104341454
可以看到该对象的实例数没有下降到0。
【Caffeine服】起始内存
image-20201101105100049
【Caffeine服】2000个机器人模拟登陆后下线,并手动调用FullGC后查看内存曲线
image-20201101105137160
这里看到内存曲线回到了起服时的模样,再查看堆dump记录
image-20201101104640103
可以看到,对象实例个数也被回收了,那么这里剩余的实例个数1是怎么回事,这里涉及到Caffeine的原理,留个悬念,等下篇文章再讲解,有兴趣关注一波,后期准备写个Caffeine系列教程。
通过以上对比,可以得出Caffeine具备“自动”清空缓存过期数据的机制,并且可以解决我们游戏中一直存在的内存问题。
总结
目前对Caffeine的替换已经提交到线上运行了,由于目前网上相关教程偏少,因而后续准备写一系列Caffeine相关的文章进行解密,有兴趣的关注一波。
img
java image 内存不足_一招解决游戏内存不足的神器Caffeine相关推荐
- java 实现 内存池_从连接池到内存池
注:内容微调,修改标题,让题文匹配. 如果将互联网应用比喻成冲浪的话, 可能需要先学会在"池"中游泳. 引子 AI赋能万物,老码农的伙伴们也曾经开发了一个基于图数据库的知识问答系统 ...
- java jvm 内存参数_深入详解JVM内存模型与JVM参数详细配置
对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...
- C语言与JAVA内存管理_深入理解C语言内存管理
之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及 ...
- c++ thread 内存泄漏_使用 ThreadLocal如何避免内存泄露?
作者:鲁毅 juejin.im/post/5e0d8765f265da5d332cde44 1.ThreadLocal的使用场景 1.1 场景1 每个线程需要一个独享对象(通常是工具类,典型需要使用的 ...
- 该内存不能为read的解决办法:内存不能为read修复工具
相信我们中的很多使用电脑的人都碰到过,有时候咚的一声弹出一个对话框,该内存不能为read错误提示, ,然后软件关闭,让人摸不着头脑.本站为你列出内存不能为read的原因和提供内存不能为read修复工具 ...
- 怎样清理苹果手机内存空间_苹果机天天显示内存不足,怎样能快速有效的清理内存?长知识了...
苹果机天天显示内存不足,怎样能快速有效的清理内存?长知识了 苹果手机的内存空间向来都是人们比较吐槽的点,每一个内存区间的差价高达一千元.很多人可能就会考虑是不是买一个空间稍微小一点的,节约钱的同时,性 ...
- 1709 ltsb 内存占用_一次C++伪“内存泄漏”的排查之旅
前段时间做一个需求,需要用到一个本地词典文件.该词典原始文件超过2G,在服务启动的时候加载到内存中,并且保持词典数据的热加载,也就是不停服更新词典数据到服务进程的内存中. 之前有同事在其他项目中有热更 ...
- linux内存占用过高怎么解决,centos7内存占用过高处理方法
博士有几台frps服务器都出现了内存占用过高的现象,然后会出现CPU使用率飙升,网上找到这个清理buff/cache缓存脚本,希望有效果. 博士在找到这个脚本的时候也学到了一个关于Linux的知识点, ...
- mysql内存爆_线上MySQL机器内存爆掉原因分析与解决
现象: 阿里金融某业务的MySQL机器的内存每隔几天就会增长,涨上去后,却不下来.累积后内存爆掉. 分析: 此业务是间隔的对MySQL有大访问,其它时间几乎无访问.排查发现,内存涨时,一般会有MySQ ...
- accessdeniedexception: 不允许访问_一招解决JDK9以上非法反射访问警告
如果觉得文章好看,欢迎点赞.同时欢迎关注微信公众号:氷泠之路. 1 问题描述 JDK9以上很多库都有这种非法反射访问的警告,比如protostuff: 解决方法两个: JDK降级 添加JVM参数 2 ...
最新文章
- HTML - embed 与 object 之争
- scater分析单细胞转录组数据代码
- RecyclerView
- linux ubuntu16.04 编译opencv教程(没编过,有时间再弄,推流不用opencv也行的)
- MyBatis快速入门及深入
- C#中用WebClient.UploadData 方法上载文件数据
- 关于程序员面试时的智力题集锦
- 2019牛客多校第二场F Partition problem(暴搜)题解
- JUC学习之CountDownLatch入门
- centos配置maven环境
- 超像素池化弱监督语义分割
- 使用Java调用shell脚本时遇到的问题
- Windows10正式版为什么没有休眠选项?
- Excel 中固定行标题和列标题
- Hadoop初入门的坑
- video 设置 poster,默认显示视频第一帧
- C++Primer 习题 第7章
- matlab工具箱分析关节力矩,在matlab工具箱中,以下选项中哪个方法是用来计算动力学力矩?...
- 机器学习与各种技术之间的关系
- c语言冒泡排序项目总结,C语言冒泡排序法心得
热门文章
- 4.剑指Offer --- 解决面试题的思路
- 3.安装Discuz
- javascript中的options.add() options.remove() options(index)或options.item(index)
- java中float double利用BigDecimal运算
- matlab R2017b 初始化缓慢的问题
- Java虚拟机知识点【方法调用】
- [bzoj1510][POI2006]Kra-The Disks_暴力
- Nginx: 解决connect() to xxxx failed (13: Permission denied) while connecting to upstream的问题
- eclipse常用快捷键整理
- JavaScript(二)基本概念