JVM调优(一)
- 什么时候会有内存泄漏,怎么排查?
答:
首先内存泄漏是堆中的一些对象不会再被使用了,但是无法被垃圾收集器回收,如果不进行处理,最终会导致抛出 java.lang.OutOfMemoryError
异常。
内存泄露:
- 不需要使用的对象被其他对象不正确的引用,导致无法回收。
- 对象生命周期过长
内存泄漏的8中情况:
-
大量使用静态集合类(
HashMap、LinkedList
等),静态变量的生命周期和JVM程序一致,在程序结束之前,静态变量不会被释放,导致内存泄漏。(属于生命周期过长) -
单例模式的静态特性,也会导致生命周期过长,如果单例对象持有外部对象的引用,会导致外部对象不会被回收。
-
内部类持有外部类:每个非静态内部类都会持有外部类的隐式引用,假如
a
为非静态内部类,b
为a
的外部类,如果b
包含了大量对象的引用,非常占用内存空间,那么如果我们创建了非静态内部类a
,此时即使b
对象不再被使用了,也无法回收,占用内存空间,导致内存泄漏。解决办法:如果内部类不需要访问外部类的成员信息,可以考虑转换为静态内部类。
-
各种连接(数据库连接、网络连接和IO连接)未及时关闭,导致大量对象无法回收,造成内存泄漏。
-
变量不合理的作用域:一个变量的定义的作用范围大于其适用范围,很有可能造成内存泄露。
-
改变哈希值:
当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了。
否则,对象修改后的哈希值与最初存入HashSet集合时的哈希值就不同了,这种情况下,即使在contains方法使用该对象的当前引用作为参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致HashSet集合中无法单独删除当前对象,造成内存泄漏
为什么改变哈希值之后找不到对象?因为根据存入时的哈希值去寻找放入的位置,而改变哈希值之后,再去查找就按照新的哈希值所对应的位置去查找,肯定找不到。
这也是 String 为什么被设置成了不可变类型,我们可以放心的把 String 存入 HashSet,或者把String当作 HashMap 的 key 值。
public class ChangeHashCodeTest {public static void main(String[] args) {HashSet<Point> set = new HashSet<>();Point cc = new Point();cc.setX(10); // hashCode = 10set.add(cc);cc.setX(20); // hashCode = 20System.out.println("set remove = " + set.remove(cc));set.add(cc);System.out.println("set.size = " + set.size());/*** 输出:* set remove = false* set.size = 2*/} } class Point {int x;public int getX() {return x;}public void setX(int x) {this.x = x;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Point point = (Point) o;return x == point.x;}@Override public int hashCode() {return x;} }
-
缓存泄露:
一旦把对象引用放入到缓存中,他就很容易遗忘。比如:之前项目在一次上线的时候,应用启动奇慢,就是因为代码会加载一个表的数据到缓存中,测试环境只有几百条数据,而生产环境有几百万的数据。
对于这个问题,可以使用WeakHashMap代表缓存,此Map的特点是:当除了自身有key的引用外,此key没有其他引用,那么此map会自动丢弃此值。
-
ThreadLocal
ThreadLocal的实现中,每个Thread维护一个ThreadLocalMap映射表,key是ThreadLocal实例本身,value是真正需要存储的Object。
ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统GC时,这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value。
如果当前线程迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,造成内存泄漏。
如何解决此问题?
第一,使用ThreadLocal提供的remove方法,可对当前线程中的value值进行移除;
第二,不要使用ThreadLocal.set(null) 的方式清除value,它实际上并没有清除值,而是查找与当前线程关联的Map并将键值对分别设置为当前线程和null。
第三,最好将ThreadLocal视为需要在finally块中关闭的资源,以确保即使在发生异常的情况下也始终关闭该资源。
try {threadLocal.set(System.nanoTime()); } finally {threadLocal.remove(); }
排查内存泄漏:
可以查看泄露对象
到GC Roots
的引用链,找到泄露对象在哪里被引用导致无法被回收
- JVM常见配置
堆设置
-Xms3550m 初始堆大小
-Xmx3550m 最大堆大小
-XX:NewSize=1024 设置年轻代大小
-XX:NewRatio=4 设置年轻代和年老代的比值.如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=8 设置年轻代中Eden区与一个Survivor区的比值,默认为8
-XX:MaxPermSize=256m 设置持久代大小
收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数.并行收集线程数.
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n)
并发收集器设置
-XX:+CMSIncrementalMode:设置为增量模式.适用于单CPU情况.
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数.并行收集线程数.
- JVM的堆配置过大的副作用有哪些?
答:JVM的堆内存配置过大,可能要面临的问题有:
- 回收大块堆内存而导致的长时间的时间停顿。
- 如果因为程序设计失误,将大对象从磁盘读取到内存中,可能会导致大对象在分配时直接进入老年代,没有在 Minor GC 中被清理掉。这样会导致频繁的发生 Full GC,给用户的体验是程序每个几分钟就停顿十几秒,非常卡顿。
扩展:JVM的堆配置过小的副作用有哪些?
- Minor GC 过于频繁
- 如果出现堆内存溢出
java.lang.OutOfMemoryError Java heap space
,该如何解决?
答:解决思路如下:
- 首先需要拿到
堆转储快照
进行分析,查看导致 OOM 的对象是否有必要存在,并且分析清除是因为哪些对象导致了 OOM - 如果是内存泄漏导致 OOM,可以查看
泄露对象
到GC Roots
的引用链,找到泄露对象在哪里被引用导致无法被回收 - 如果不是内存泄漏,那么说明内存中的对象都是存活的,导致 OOM,这时应该检查虚拟机的堆内存设置是否有向上调整的空间。并且检查是否存在
对象生命周期过长
、存储结构不合理
的情况,减少程序运行中的内存消耗。
扩展说明:因为存储结构不合理导致堆内存溢出(来自于《深入理解Java虚拟机第3版》)
举例:使用 HashMap<Long, Long>
存储大量的数据,会导致浪费大量的空间,因为 HashMap 的空间效率使用太低。
对于一个 HashMap<Long, Long>
来说,有效数据只有 Key、Value 的两个 long 型数据,占 16字节,long 数据被包装为 java.lang.Long 对象后,就分别具有 8 字节的 Mark Word、8字节的 Klass 指针、8字节的 long 型数值。两个 Long 对象组成 Map.Entry 之后,又多了 16 字节的对象头、8字节的 next 字段、4字节的 int 型的 hash 字段、4字节的空白填充(为了对齐)还有 HashMap 中对这个 Entry 的 8 字节的引用,这样实际占用的内存为:(Long(24byte) * 2) + Entry(32byte) + HashMap Ref(8byte)=88byte
,空间效率仅仅为 16byte / 88byte = 18%。
- 写代码时候有没有什么方式尽量减少Full GC的概率?
答:
- 避免一次性加载大量数据加载到内存,比如excel导入导出,jdbc数据库查询
- 避免大对象的代码处理业务链流程过长,比如aop中获取到了对象参数,大对象捕获到了,导致对象生命周期变长了,没及时释放。
- 禁止使用system.gc方法
- 避免在使用threalocal后,未主动调用remove方法,尽量避免大对象的使用,以及频繁的创建和销毁。更要避免全局锁的竞争等。
相关文章:
JVM调优(一)
什么时候会有内存泄漏,怎么排查? 答: 首先内存泄漏是堆中的一些对象不会再被使用了,但是无法被垃圾收集器回收,如果不进行处理,最终会导致抛出 java.lang.OutOfMemoryError 异常。 内存泄露: …...
Parallels Desktop 19中文-- PD19最新安装
Parallels Desktop 19可以让我们在Mac电脑上运行Windows和其他操作系统,而无需重启计算机。这款软件的稳定性较高,能够在Mac上同时运行多个操作系统,如Windows、Linux等,而无需重启电脑。它可以让用户无缝地在不同操作系统之间切换…...
【c++】向webrtc学比较1:AheadOf、IsNewerTimestamp
webrtc源码分析-rtp序列号新旧比较 大神文章分析的非常到位。大神分析:AheadOrAt(a, b)是判断a是否比b新的核心,其原理是这样的:rfc1982规定了序列号递增间隔不能超过取值范围的1/2(这是自己理解的),那么要判断a是否比b新,只要判断b到a的递增是否在1/2即可,递增超过1/2,…...
华为云云耀云服务器L实例评测|企业项目最佳实践之docker部署及应用(七)
华为云云耀云服务器L实例评测|企业项目最佳实践系列: 华为云云耀云服务器L实例评测|企业项目最佳实践之云服务器介绍(一) 华为云云耀云服务器L实例评测|企业项目最佳实践之华为云介绍(二) 华为云云耀云服务器L实例评测࿵…...
MAC上使用Wireshark常见问题
文章目录 介绍正文启动异常-Permission denied解决方法 过滤协议和地址指定源地址和目的地址调整 time format 介绍 简单记录Wireshark在日常使用过程中的遇到的小case。 正文 Wireshark相较于tcpdump使用较为简单,交互也更为友好。 点击Start即可启动抓包 启动…...
在C++中++a和a++有什么区别?
2023年10月16日,周一中午 a和a在语义上的区别 a是先进行运算(增加1),然后返回新值。 a是先返回原值,然后进行运算(增加1)。 a和a在效率上的区别 a直接返回新值,不需要临时变量保存原值。 而a需要先返回原值,然后再进行增加1的操作。这需要使用一个临时变量来保存…...
NewStarCTF2023公开赛道-压缩包们
题目提示是压缩包 用010editor打开,不见PK头,补上50 4B 03 04 14 00 00 00 将文件改成.zip后缀,打开,解压出flag.zip 尝试解压,报错 发现一串base64编码 SSBsaWtlIHNpeC1kaWdpdCBudW1iZXJzIGJlY2F1c2UgdGhleSBhcmUgd…...
oracle数据库增加表空间数据文件
查询数据文件:select * from dba_data_files order by file_name; 增加:alter tablespace 数据库名 add datafile data size 34359721984;...
【08】基础知识:React中收集表单数据(非受控组件和受控组件)
一、概念 非受控组件: 页面中所有输入类的 DOM,现用现取。 给组件绑定 ref 属性,在需要时通过 ref 获取相应值。 受控组件: 页面中所有输入类的 DOM,随着输入,将内容维护到状态 state中,当…...
数据结构之堆排序和前,中,后,层序遍历,链式二叉树
首先我们要知道升序我们要建小堆,降序建大堆,这与我们的大多人直觉相违背。 因为我们大多数人认为应该将堆顶的数据输出,但如果这样就会导致堆顶出堆以后,堆结构会被破坏,显然我们不能这样。 所有我们反其道而行&…...
多线程中ThreadPoolExecutor.map()中传递多个参数
with concurrent.futures.ThreadPoolExecutor(max_threads) as executor:results executor.map(get_captcha_image, ip_addrs, [img_url] * len(ip_addrs)) #要传入多个参数时,每个参数都得是固定相同长度的可迭代对象# 收集结果for result in results:print(resul…...
linux centos7 环境下 no such file or directory
目录 1.问题描述2.主要原因2.1修改后代码2.2修改前代码 总结参考 1.问题描述 预览excel文件时无法找到对应的html文件 2.主要原因 异常原因:代码获取的是系统的tmp文件,但是linux环境环境中心tmp目录是没有权限的,所以不能获取系统的根目录…...
Nginx 反向代理 SSL 证书绑定域名
配置 Nginx 反向代理和 SSL 泛域名证书绑定域名 Nginx 是一个功能强大的 Web 服务器和反向代理服务器,可以用于将客户端请求转发到后端服务器,并提供安全的 HTTPS 连接。本文将介绍如何配置 Nginx 反向代理,并使用 SSL 泛域名证书绑定域名&a…...
SpringBoot 集成 JMS 与 IBMMQ 代码示例教程
文章目录 前言一、集成 JMS 与 IBMMQ1、pom 依赖2、yml 配置3、Properties 配置类4、Factory 连接工厂类5、配置连接认证6、配置缓存连接工厂7、配置事务管理器8、配置JMS模板9、消息发送与接收 总结 前言 SpringBoot 集成 IBMMQ,实现两个服务间的消息通信。 一、集…...
大模型之Prompt研究和技巧
大模型之Prompt研究和技巧 大模型之Prompt编写简介组成技术Zero-ShotFew-shotCOTCOT-SCTOTGoTReAct 大模型之Prompt编写 简介 Prompt是是给 AI **模型的指令,**一个简短的文本输入,用于引导AI模型生成特定的回答或执行特定任务。 Prompt是你与语言模型沟…...
掌握Golang匿名函数
一个全面的指南,以理解和使用Golang中的匿名函数 Golang以其简单和高效而闻名,赋予开发人员各种编程范式。其中一项增强代码模块化和灵活性的功能就是匿名函数。在这篇正式的博客文章中,我们将踏上探索Golang匿名函数深度的旅程。通过真实世…...
HarmonyOS云开发基础认证---练习题二
【判断题】 2/2 Serverless是云计算下一代的默认计算范式。 正确(True) 【判断题】 2/2 接入认证服务后,用户每次收到验证码短信都需要开发者买单。 错误(False) 【判断题】 2/2 认证服务手机号码登录需要填写国家码。 正确(True) 【判断题】 2/2 在Cloud Functi…...
ffmpeg视频解码器的配置选项含义
lowres的含义 lowres是AVCodecContext结构体中的一个成员变量,用于指定编解码器的降低分辨率级别。 在某些情况下,为了加快编解码的速度或减少计算资源的消耗,可以通过设置lowres参数来降低编解码器的分辨率级别。这将导致编解码器在处理视…...
enter ubuntu boot option in virt-manager
在全屏模型下,启动过程中按下F8或者Ctrl F8。 参考:https://serverfault.com/questions/463024/how-do-i-access-the-f8-bootmenu-while-booting-a-windows-2008r2-kvm-guest-vm...
电商运营该如何做 AB 测试
更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 近年,电商行业进入了一个新的发展阶段,一方面电商市场规模持续扩大,另一方面直播电商、即时零售、社区团购等新兴电商业态在疫情…...
go环境部署
#env 命令查看 PATH 发现 #这两条环境变量是把 通过brew 安装的所有程序加入到环境变量中,其中就包含了go /opt/homebrew/sbin /opt/homebrew/bin#mac 系统 将原本 brew 安装的 go 1.20.5版本卸载 brew uninstall go #然后 去官网下载 https://go.dev/dl/ 想要的版本 1.21.0 …...
HTTP/2 中的漏洞
另一个热门漏洞是 CVE-2023-44487。 该漏洞与 HTTP/2 协议实施中的一个缺陷有关,可用于实施 DDoS 攻击。使用该漏洞的攻击被命名为 HTTP/2 快速重置。 为什么它很危险 要利用该漏洞,攻击者需要在 HTTP/2 会话中打开大量请求,然后在不等待服…...
智能油烟机 优化烹饪体验
如果说空调是夏天最伟大的发明,那么油烟机则是健康厨房的伟大推进者。随着科技的发展,智能化的油烟机逐渐走进了人们的日常生活。每当我们在爆炒、油炸食物的时候,油烟总能呛得人眼睛痛、鼻子难受,传统的油烟机面前我们还需要手动…...
啥?PS一秒成图?Adobe的逆天黑科技大公开
在日前举行的 Adobe MAX 创意大会上,Adobe Adobe Firefly Image 2(萤火虫二代成像模型)、Firefly Vector Model(萤火虫矢量模型)和Firefly Design Model(萤火虫设计模型)。 Firefly矢量模型是世…...
扫描器(xray和bp联动)
文章目录 分类主动扫描和被动扫描bp与xray联动 分类 扫描器分为对web的扫描器和对主机的扫描器 主动扫描和被动扫描 主动扫描: 输入某个URL,然后由扫描器中的爬虫模块爬取所有链接,对GET、POST等请求进行参数变形和污染,进行重放测…...
[C++]:1.初识C++和C语言缺陷补充。
初识C和C语言缺陷补充 一.主要内容:二.具体内容:一: 作用域1.命名空间:2.函数声明和定义:3.不存在命名冲突的情况: 二.输入输出:1.基本输入输出:2.关于std的展开: 三.函数…...
BUUCTF学习(三): PHP 代码审计
1、介绍 2、解题 (1)查看网页源代码 (2)返回链接 (3)代码审计...
推荐《Blue prison》
电视动画片《蓝色监狱》改编自金城宗幸原作、野村优介作画的同名漫画作品,于2021年7月31日宣布电视动画化的消息 [1]。该片由8Bit负责动画制作,于2022年10月9日起播出 [2],全24集。 该作评为Anime Corner 2022年年度体育动画 [24]࿰…...
goland安装教程
安装版本: goland-2023.2.3.exe...
java中okhttp和httpclient那个效率高
在比较OkHttp和HttpClient的效率时,需要考虑多个因素,包括性能、吞吐量、资源消耗等。这些因素往往取决于具体的使用场景和需求。 OkHttp是一个由Square开发的现代化HTTP客户端库,它在Android平台上广泛使用,并且也可以在Java应用…...
龙口市建设局网站/seo搜索如何优化
查找信息,Aug 31 18:25:36 collect-28 kernel: printk: 58 messages suppressed. 此报错需要修改内核信息如下; (1) 加大 ip_conntrack_max 值: 查出原本的 ip_conntrack_max 值,指令: cat /proc/sys/net/ipv4/ip_conntrack_max 写…...
给手机开发网站/免费推广产品平台有哪些
今天继续接着CSS盒子模型补充,CSS基础学习十三:盒子模型和CSS基础学习十四:盒子模型补充之display属 性设置都是介绍了盒子模型中的内容概括。开始今天的主题:外边距合并。 外边距合并指的是,当两个垂直外边距相遇时&…...
网站开发教程PDF微盘下载/淘数据官网
Visual Basic .NET 教程 模块五 菜单栏、工具栏、状态栏 能力目标:能够设计、创建和使用菜单、工具栏和状态栏 知识目标:掌握菜单控件、工具栏控件和状态栏控件常用的属性、方法和事件 一个典型的Windows应用程序必然包含菜单、工具栏和状态栏&#x…...
保定电子商务网站建设/关键词搜索优化公司
关于Spring集成Quartz有2种方法: 1. JobDetailBean. 2. MethodInvokeJobDetailFactoryBean. 以下从自身使用和理解以及掌握的知识对其进行阐述。 需要注意的是,在使用Spring集成Quartz的时候,一定不要忘记引入spring-support这个包: <!-- …...
现在可以做网站么/seo搜索是什么意思
题目:http://acm.hdu.edu.cn/showproblem.php?pid1051 经典的贪心题,按照l,w排好序后进行扫描标记,注意逻辑即可。 #include <iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespac…...
天空台108网站找手工活带回家做/百度软件中心下载
入门HelloWorld新建项目Configure your new project部分选中 Include C Support 复选框Next正常填写所有其他字段并完成向导接下来几个部分在向导的Customize C Support 部分,您可以使用谢列选项自定义项目:C Standard : 使用下拉列表选择使用的C标准。选…...