记一次生产大对象及GC时长优化经验
最近在做一次系统整体优化,发现系统存在GC时长过长及JVM内存溢出的问题,记录一下优化的过程
面试的时候我们都被问过如何处理生产问题,尤其是线上oom或者GC调优的问题更是必问,所以到底应该如何发现解决这些问题呢,用真实的场景实操,更具有说服性。
一:如何发现
1.发现经过如下,首先pass服务的pod不停自动触发重启,因为pass配置系统health接口访问超时,通过系统的grafana监控发现二点异常,1.GC时间大量超时40s+,2.堆内存达到24G(也是我们配置最大的内存,触发OOM)
监控如下:
所以我们可以梳理出以下链路
二:如何优化
1,我们dump系统的在业务低谷期的内存情况,看看业务的低谷期时系统中是否存在不合理的大对象,如果有肯定是要优化掉的,因为业务高峰期会肯定分配一些局部变量大对象,需要给他们腾空间,可以理解先优化最简单的,再优化运行中产生的,结果还真的发现在这个GoodsSetNormalGoodsCache类的中cache对象,存了一个近1200W(并且随业务持续增长)的内存大对象,用于全局skc分站点上下架的缓存信息
dump如下:
1.巧用redis优化大对象
优化策略:大家很容易想到将map由JVM内存移入redis的hash结构中存储(面试过很多人都说把oom的对象直接剔除,其实很多时候我们处理的场景是不允许删除,如果直接移除可以解决问题,我相信大部分开发就不会加载部分大对象进入内存,加载进去必然是为了快速查询全量数据),存储结构如下图:
但是实际上线后,生产环境中又遇到新的问题,这个keyQPS很高达到几万qps,因为业务逻辑增量任务需要不停且大量的查询skc在不同站点的上下架信息,必然也导致这个key是一个热key
如图:(注意这里的元素个数是900w,因为在做初始化)
当然,系统中出现热key不是问题,问题在于redis也是个大key,导致数据产生倾斜,最高的节点和最低的节点相差一个G的数据,并且我们联系运维同学重平衡也无法生效,于是我们思考应该如何从开发角度解决这个问题,究其根本原因是key太大,存储的数据太多,那么我们的场景并没有统计功能,也就是说这个key我们可以拆开,降低单个key的大小,QPS自然也就降低下去了。
如图:
优化后重新写入数据,我们可以清晰看出倾斜的数据节点恢复正常了
2.巧用布隆过滤器优化大对象
上面我们dump了系统空闲水位的大对象也进行优化了,那么代码运行时产生的局部大对象,我们的优化思路时什么呢,正好我们的代码中,有一个很大的set存储商品集(可以理解为一些条件的skc集合)全量的skc,用于商品更新的时候和上一次数据进行对比产生增量,你可以理解为一个集合数据要更新,那么更新后产生了哪些新增的数据我们怎么知道呢,肯定是存了一份之前的历史数据,那这个数据就装在set,现在的问题是需要更新的商品集很多,所以set也很多,导致set的大对象的频繁创建和回收,触发GC压力很大
我们的优化思路是,1.首先这个set不是用于常驻查询,换句话说就不是热key,用于临时操作,那么放在redis就得不偿失了,当然了也是可以做到,2.这个set的作用主要用于存储全量进行判断是否存在,但是问题在于内存开销大,有没有一种结构可以内存占用小又可以判断元素是否存在,这个容器就是即布隆过滤器
我们利用guava的布隆过滤器写个简单的程序说明优化流程,以及内存占用对比
public class BloomFilterUtils {/*** builderBloomFilter** @param size 长度* @param fpp 误判率* @return*/public static BloomFilter<String> builderBloomFilter(int size, double fpp) {BloomFilter<String> bf = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), size, fpp);return bf;}public static void main(String[] args) {HashSet<String> set = new HashSet<>();ArrayList<String> list = new ArrayList<>();//存储1000w元素,误判率百万分一,即10个误判BloomFilter<String> bf = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 1000 * 10000, 0.0000001d);for (int i = 0; i <= 1000 * 10000; i++) {String skc = UUID.randomUUID().toString();set.add(skc);list.add(skc);bf.put(skc);}System.out.println("布隆内存占用 = " + RamUsageEstimator.humanSizeOf(bf));System.out.println("set 内存占用:" + RamUsageEstimator.humanSizeOf(set));System.out.println("list 内存占用:" + RamUsageEstimator.humanSizeOf(list));}
}
运行结果:
可以看出1000w-skc(字符串模拟skc)的存储,set占用最高,因为要记录额外的信息(hashcode)用于判重,list结构其次,而布隆仅仅为35分之一(受误判率影响),当然业务场景要允许存在个别误判
三:总结
昨晚上述优化后,我们成功将gc时间降低到5s内
- 对于jvm大对象的优化,我们要在于要明确大对象为什么会产生,结合业务和相关技术,采取最优的方式,既优化了大对象,也不损失性能甚至还能提速,而不是八股文中的直接移除一刀切
2)oom或者gc时间增长的问题,并不是出现问题才排查修复,我们更应该关注和监控系统空闲时水位线,不要让内存慢慢的泄漏,从而导致出现压死骆驼的最后一个稻草时,我们才能发现,那样就太慢了
相关文章:

记一次生产大对象及GC时长优化经验
最近在做一次系统整体优化,发现系统存在GC时长过长及JVM内存溢出的问题,记录一下优化的过程 面试的时候我们都被问过如何处理生产问题,尤其是线上oom或者GC调优的问题更是必问,所以到底应该如何发现解决这些问题呢,用真实的场景实操ÿ…...
Vue项目为页面添加水印效果
最近在做项目,有这样要求,需要在指定容器中添加水印,也可不设置容器,如果没有容器,则添加在整个页面中,即body,当接到这个需求的时候我第一想的方法就是用canvas来实现,话不多说搞起…...
两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…...

试过GPT-4V后,微软写了个166页的测评报告,业内人士:高级用户必读
一周之前,ChatGPT迎来重大更新,不管是 GPT-4 还是 GPT-3.5 模型,都可以基于图像进行分析和对话。与之对应的,多模态版GPT-4V模型相关文档也一并放出。当时 OpenAI 放出的文档只有18页,很多内容都无从得知,对…...
使用Python构造VARIMA模型
简介 VARMA(p,q)结合了VAR和VMA模型,其中p是向量自回归(VAR)模型的滞后期数,q是VMA模型的移动平均的阶数。 VARMA是ARMA的推广,它将ARMA模型扩展到多个时间序列变量的情况,通过VAR和VMA的线性组合来描述多个时间序列变量之间的联…...

Java基于SpringBoot+Vue的考研资讯平台
1 简介 大家好,我是程序员徐师兄,今天为大家带来的是Java基于SpringBootVue的考研资讯平台 Java基于SpringBoot的考研资讯平台,在系统当中学生可以根据不同的信息来实现该网站的考研资讯平台信息的管理。 系统主要分为前台和后台。主要包括…...

信钰证券:9月以来A股20家银行 获机构不同批次调研
Wind数据显现,自9月份以来,已经有20家银行获安排不同批次调研。其间常熟银行、瑞丰银行被调研次数较多,别离为20次、11次;宁波银行、渝农商行获安排调研家数居前,别离为206家、128家。从上市银行宣布的调研情况来看&am…...

应用商店优化的好处有哪些?
应用程序优化优势包括应用在商店的可见性和曝光度,高质量和被相关用户的更好发现,增加的应用下载量,降低用户获取成本和持续增长,增加应用收入和转化率以及全球受众范围。 1、提高知名度并在应用商店中脱颖而出。 如果用户找不到…...

MacOS Pro笔记本硬盘升级纪实
背景 MacPro 2015 mid的苹果本,忽然心血来潮想升级一下SSD。三个步骤:做启动盘,时间机器备份,插新的SSD盘恢复。 过程 下载MacOS,macOS Monterey 12.7官方原版镜像: https://swcdn.apple.com/content/do…...

景联文科技:3D点云标注应用场景和专业平台
3D点云技术之所以得到广泛发展和应用,主要是因为它能够以一种直观、真实和全面的方式来表示和获取现实世界中的三维信息。 3D点云的优势: 真实感和立体感:3D点云数据能够呈现物体的真实感和立体感,使观察者能够更直观地理解物体的…...
基于R语言的水文、水环境模型优化技术及快速率定方法
【阅读原文】:基于R语言的水文、水环境模型优化技术及快速率定方法与多模型案例实践 【内容简介】: 专题一、最速上升法、岭分析以及响应曲面模型 1.最速上升路径 2.信赖域 3.响应面模型 4.二阶响应面 5.岭分析 专题二、Kriging插值与优化方法 …...

学习网络安全得多少费用?网络安全入门了解
前言 网络安全是指对网络系统、硬件、软件和系统数据的保护。不因偶然或者其它原因导致破坏、更改和数据泄露情况。确保网络安全,防止网站被攻击、系统被病毒感染等。随着网络的快速发展,越来越多的用户和公司认识到网络安全的重要性,许多人…...

记录一次线上fullgc问题排查过程
某天,接到测试部门反馈说线上项目突然很快,由于当前版本代码和上一版本相比就多了一个刚上线了一个5分钟1次的跑批任务,先关闭次任务后观察是否卡顿,并检查堆内存是否使用完造成频繁gc 1.通过jmap命令查看堆内存中的对象 2.生成当…...
设计接口应该考虑的因素以及遵循的原则
设计接口应该考虑的因素: 接口的业务定位 接口的安全性 接口的可扩展性 接口的稳定性 接口的跨域性 接口的协议规则 接口的路径规则 接口单一原则 接口过滤及接口组合 1.职责原则 在设计接口时,必须明确接口的职责,即接口类型&…...

【产品】智能结构仿真软件AIFEM 2023R2新版本功能介绍
AIFEM是由天洑自主研发的一款通用的智能结构仿真软件,助力用户解决固体结构相关的静力学、动力学、振动、热力学等实际工程问题,软件提供高效的前后处理工具和高精度的有限元求解器,帮助用户快速、深入地评估结构的力学性能,加速产…...
探索数据库的世界:DB、DBMS、DBA、DBS的全面介绍
目录 DB数据库(Database) DBMS数据库管理系统(Database Management System): DBA数据库管理员(Database Administrator): DBS数据库系统(Database System) 总结: DB数据库(Database) 概念: 存储数据的集合,DB可以包含各种类型的数据,文…...

【JVM】初步认识Java虚拟机
🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 JVM 一、初识JVM1.1 什么是JVM1.2 JVM的功能…...
JAVA设计模式-模板模式
一.概念 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 使用了JAVA的继承机制,在抽象类中定义一个模板方法,该方法引用了若干个抽象方法࿰…...
day007
删除链表第n个节点 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val …...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...

【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...