问题定位:

最近奉命解决游戏中一直在的内存不够的问题,最终定位到底层的缓存机制使用的是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相关推荐

  1. java 实现 内存池_从连接池到内存池

    注:内容微调,修改标题,让题文匹配. 如果将互联网应用比喻成冲浪的话, 可能需要先学会在"池"中游泳. 引子 AI赋能万物,老码农的伙伴们也曾经开发了一个基于图数据库的知识问答系统 ...

  2. java jvm 内存参数_深入详解JVM内存模型与JVM参数详细配置

    对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...

  3. C语言与JAVA内存管理_深入理解C语言内存管理

    之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及 ...

  4. c++ thread 内存泄漏_使用 ThreadLocal如何避免内存泄露?

    作者:鲁毅 juejin.im/post/5e0d8765f265da5d332cde44 1.ThreadLocal的使用场景 1.1 场景1 每个线程需要一个独享对象(通常是工具类,典型需要使用的 ...

  5. 该内存不能为read的解决办法:内存不能为read修复工具

    相信我们中的很多使用电脑的人都碰到过,有时候咚的一声弹出一个对话框,该内存不能为read错误提示, ,然后软件关闭,让人摸不着头脑.本站为你列出内存不能为read的原因和提供内存不能为read修复工具 ...

  6. 怎样清理苹果手机内存空间_苹果机天天显示内存不足,怎样能快速有效的清理内存?长知识了...

    苹果机天天显示内存不足,怎样能快速有效的清理内存?长知识了 苹果手机的内存空间向来都是人们比较吐槽的点,每一个内存区间的差价高达一千元.很多人可能就会考虑是不是买一个空间稍微小一点的,节约钱的同时,性 ...

  7. 1709 ltsb 内存占用_一次C++伪“内存泄漏”的排查之旅

    前段时间做一个需求,需要用到一个本地词典文件.该词典原始文件超过2G,在服务启动的时候加载到内存中,并且保持词典数据的热加载,也就是不停服更新词典数据到服务进程的内存中. 之前有同事在其他项目中有热更 ...

  8. linux内存占用过高怎么解决,centos7内存占用过高处理方法

    博士有几台frps服务器都出现了内存占用过高的现象,然后会出现CPU使用率飙升,网上找到这个清理buff/cache缓存脚本,希望有效果. 博士在找到这个脚本的时候也学到了一个关于Linux的知识点, ...

  9. mysql内存爆_线上MySQL机器内存爆掉原因分析与解决

    现象: 阿里金融某业务的MySQL机器的内存每隔几天就会增长,涨上去后,却不下来.累积后内存爆掉. 分析: 此业务是间隔的对MySQL有大访问,其它时间几乎无访问.排查发现,内存涨时,一般会有MySQ ...

  10. accessdeniedexception: 不允许访问_一招解决JDK9以上非法反射访问警告

    如果觉得文章好看,欢迎点赞.同时欢迎关注微信公众号:氷泠之路. 1 问题描述 JDK9以上很多库都有这种非法反射访问的警告,比如protostuff: 解决方法两个: JDK降级 添加JVM参数 2 ...

最新文章

  1. HTML - embed 与 object 之争
  2. scater分析单细胞转录组数据代码
  3. RecyclerView
  4. linux ubuntu16.04 编译opencv教程(没编过,有时间再弄,推流不用opencv也行的)
  5. MyBatis快速入门及深入
  6. C#中用WebClient.UploadData 方法上载文件数据
  7. 关于程序员面试时的智力题集锦
  8. 2019牛客多校第二场F Partition problem(暴搜)题解
  9. JUC学习之CountDownLatch入门
  10. centos配置maven环境
  11. 超像素池化弱监督语义分割
  12. 使用Java调用shell脚本时遇到的问题
  13. Windows10正式版为什么没有休眠选项?
  14. Excel 中固定行标题和列标题
  15. Hadoop初入门的坑
  16. video 设置 poster,默认显示视频第一帧
  17. C++Primer 习题 第7章
  18. matlab工具箱分析关节力矩,在matlab工具箱中,以下选项中哪个方法是用来计算动力学力矩?...
  19. 机器学习与各种技术之间的关系
  20. c语言冒泡排序项目总结,C语言冒泡排序法心得

热门文章

  1. 4.剑指Offer --- 解决面试题的思路
  2. 3.安装Discuz
  3. javascript中的options.add() options.remove() options(index)或options.item(index)
  4. java中float double利用BigDecimal运算
  5. matlab R2017b 初始化缓慢的问题
  6. Java虚拟机知识点【方法调用】
  7. [bzoj1510][POI2006]Kra-The Disks_暴力
  8. Nginx: 解决connect() to xxxx failed (13: Permission denied) while connecting to upstream的问题
  9. eclipse常用快捷键整理
  10. JavaScript(二)基本概念