JVM原理和调优(读这一篇就够了)
前言
抛2个问题:
1、export JAVA_OPTS="-Xms256m -Xmx512m -Xss256m -XX:PermSize=512m -XX:MaxPermSize=1024m -Djava.rmi.server.hostname=136.64.45.24 -Dcom.sun.management.jmxremote.port=9315 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
---上面的"-Xms256m -Xmx512m -Xss256m -XX:PermSize=512m -XX:MaxPermSize=1024m“分别是什么意思
2、为什么调整上面这几个参数就能让java程序不卡顿,或者不报错oom
3、java.lang.OutOfMemoryError: Java heap space和java.lang.StackOverflowError是否熟悉,分别表示了什么错误,背后出现了什么问题
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一、JVM内存模型
堆:所有new对象都放在堆里,这也是JVM优化的重点。
栈:也叫线程栈,是每个线程独立分配的内存空间,存储的包括局部变量,操作数,动态链接,方法出口。它和堆的关系其实是堆的指针引用。
本地方法栈:为虚拟机用到的Native方法服务。Native方法是java通过JNI直接调用本地C/C++库,可以认为是暴露给java的本地接口。
方法区(元空间):类装载系统会把class信息放到方法区,通过字节码引擎执行。会放常量(运行时常量池,那么什么是静态常量池),静态变量,类元信息。jdk8以后就叫元空间。
程序计数器:记录执行的代码行数的行号,比如线程暂停回来后,继续执行,就需要读取行号,继续向下执行
(一)栈的核心组成部分
局部变量表: 用于存放方法中的局部变量和参数
操作数栈: 用于存放方法执行过程中产生的中间结果
动态链接:方法区里面的符号引用转为直接引用(即:给出地址)
方法出口:记录当前执行方法执行完毕后返回主方法的下一行位置
(二)堆
所有的new对象最开始都放到Eden(伊甸)区,当Eden区沾满之后,JVM会进行一次minor gc,将发现依然存活的对象放到Survivor区,同时讲分代年龄+1(存储在object header里面),会清理eden和form区域,通过复制等算法再次将存活对象放到to区域,依次类推来回复制,当分代年龄达到15时,会挪到老年代,比如静态变量,数据库连接池,缓存就属于“老不死”。当老年代内存被占满时,就会触发full gc,full gc会对整个堆进行垃圾回收,因此非常耗时,时间很长,我们要尽量降低full gc的频次。
题外话:minor gc如何进行垃圾回收呢,这里面运用到一个可达性分析算法,里面有一个GC roots根的概念很关键,要理解一下,gc会根据该算法找出该对象的整条GC root链,定义为有效存活对象,会移动到survivor区域;剩下的对象由于找不到对象引用,因此定义为无效对象,从而进行回收。具体如下:
(为什么年轻代使用复制算法,老年代使用标记-清除算法?)
还有一种情况,只要伊甸区移动的内存大于存活区的1/2时,会直接放到老年代。
当old区内存满了后,就会触发full gc,但是发现引用还在(list还是运行),因此没法回收,但是死循环又一直在new对象,old区无内存可用,于是就OOM。
在full gc的时候针对整个heap进行寻找垃圾对象,因此会停顿用户线程(STW)。为什么要停止呢,如果不停止的话,意味着回收线程和用户线程同步执行,回收线程会认为用户线程的内存不是垃圾对象,因此不予理会,但如果用户线程很快执行完,它使用的对象就变成垃圾对象了,这时候回收线程不知道该如何处理,因此为了更好的控制内存,full gc的时候,必须暂停用户线程,回收完成后,再恢复用户线程。因此问题就出现了,如果频繁的full gc,而且收集时间非常长(因为针对整个堆内存回收)就会频繁的停止用户线程,导致系统功能暂时不可用,也就是卡顿现象或无响应。因此优化的点就一目了然: 减少full gc次数,让年轻代去收集释放垃圾对象。
二、JVM调优
为什么调优其实上面已经提前说了,所以我们调优的目的是什么呢?就是让系统更加的丝滑,让用户体验变得更好。
以下是一个亿级流量网站的一个并发计算过程demo图:
以下是关键数据计算:
日活:1E/20 = 500W。要估算每个人一天的日点击数。
日均订单:50W。这里要找业务确定转化率。
大促并发数:50W/50s = 1000单左右。这里要估算并发时间,这里拍脑袋是1分钟内。
单机并发数:1000/n。n表示是机器节点。
每单请求的数据量:1kb * 1000/n。1kb是单个请求的data大小,这个研发可以根据请求data json算出来。
单机的内存使用:300kb * 20 * 10 = 60M。300kb是n=3,20是下单逻辑中会有加减库存,优惠券,积分系统接口,10是订单查询等其他外部操作。
初始化jvm配置如下:
对应的jvm内存模型是:
每一秒产生60M对象,均放到eden区
到第13秒时,eden区内存即将占满(60*13 =780M),触发minor gc
这时候会对前12秒的对象进行回收,第13秒产生的对象由于还在执行,因此判断为有效对象,会被移动到S0区
这时候会触发jvm另外一个机制--动态年龄判断,即发现该对象大小大于survivor区内存大小的50%,会直接进入old区。因此该60M对象会直接移动到old区。因此会出现每过13秒,会有60M数据进入old区
所以old区大概多久会被占满,2000M/60 *13 = 433s。也就是大概433s后就会触发一次full gc
因此问题来了,如果这个大促持续数个小时,而每隔7分钟就执行一次full gc,势必影响用户体验和性能。那么怎么优化呢
解决策略:我们完全可以把old区的这60M对象让它在survivor区就回收,减少old区的full gc次数。因此我们需要对jvm参数进行优化配置。(阿里面试题:能否对JVM调优,使其几乎不发生full gc。答案是能)
将年轻代的内存调大(-Xmn2048M)
所以,jvm优化后的内存分配模型就出来了:
2个好处:
原来13秒就minor gc,现在延长到25秒
60M对象会在survivor区就会被回收,不会跑到old区触发full gc
(全文完)
(喜欢视频的可以去读下这个:https://www.bilibili.com/video/av79368741/?p=5)
JVM原理和调优(读这一篇就够了)相关推荐
- JVM原理及调优--网页链接收藏
此篇用于收藏大神们关于JVM原理及调优通俗易懂的文章链接,用于随时查看 JVM调优总结 JVM参数配置大全 JVM调优:选择合适的GC collector 菜菜鸟想了解下大概的JVM内存模型可以看这个 ...
- JVM原理和调优的理解和学习
JVM原理和调优的理解和学习 一.详解JVM内存模型 二.JVM中一次完整的GC流程是怎样的 三.GC垃圾回收的算法有哪些 四.简单说说你了解的类加载器 五.双亲委派机制是什么,有什么好处,怎么打破 ...
- JVM原理、调优、GC
转自:https://www.jianshu.com/p/63fe09fe1a60 jvm原理 Java虚拟机是整个java平台的基石,是java技术实现硬件无关和操作系统无关的关键环节,是java语 ...
- win7查看tomcat端口_想研究Tomcat性能调优,看这篇就够了
一.下载地址 https://tomcat.apache.org/download-80.cgi 二.安装步骤 将安装包 apache-tomcat-8.5.39.tar.gz 上传至服务器 /usr ...
- 一篇最通俗易懂的性能调优总结,这篇就够了
一,什么是性能调优? 在说什么是性能调优之前,我们先来说一下,计算机的体系结构. 如上图,简单来说包括三块:硬件.操作系统.应用程序.其实,性能调优就是调节这些内容,包括硬件.操作系统.应用程序.其中 ...
- java虚拟机工作原理图_超“强”的图文详解-JVM虚拟机底层原理与调优实战
今天我和大家分享一篇文章,文章上半部分为JVM底层原理 下半部分为调优实战 文章有点长,需要点耐心哦! 如果觉得看文章太难理解,就点击下面我投稿B站的jvm视频讲解. 还配有视频讲解:解密BATJ一线 ...
- 全面的GC原理及调优
本文介绍 GC 基础原理和理论,GC 调优方法思路和方法,基于 Hotspot jdk1.8,学习之后你将了解如何对生产系统出现的 GC 问题进行排查解决. 图片来自 Pexels 内容主要如下: G ...
- 第二十一期:老大难的GC原理及调优,这全说清楚了
本文介绍 GC 基础原理和理论,GC 调优方法思路和方法,基于 Hotspot jdk1.8,学习之后你将了解如何对生产系统出现的 GC 问题进行排查解决. 本文介绍 GC 基础原理和理论,GC 调优 ...
- 老大难的GC原理及调优,这下全说清楚了
" 本文介绍 GC 基础原理和理论,GC 调优方法思路和方法,基于 Hotspot jdk1.8,学习之后你将了解如何对生产系统出现的 GC 问题进行排查解决. 文章转载自51CTO技术栈 ...
最新文章
- python基础之python中if __name__ == '__main__': 的解析
- JAVA——基于HttpClient的通过单点登录方式(统一身份认证平台)登录正方教务系统[1999-2020]基本解决方案
- jsr133-第一二章
- 64位ubuntu kylin 16.04下制作tiny4412可用的SD启动卡
- adb shell 书籍_开发必备---你应该知道的一些 ADB 命令
- 技术人生:希望有生之年开发一个“自己的解释语言”
- Mybatis之执行自定义SQL举例
- 华为手机芯片断供,有没有可能回收旧手机解决目前困境?
- bxl类型封装转换为AD库封装
- Ttest + 秩和检验
- C语言写的一个贪吃蛇小游戏(windows系统)
- 梦行扫码付(收银台条码支付 微信钱包条码支付 支付宝二维码支付 手机APP钱包支付 PHP扫码支付 )
- 全国计算机三级答案,全国计算机三级数据库技术笔试试题(附正确答案)
- 搜索引擎排名都选乐云seo_乐云百度爱采购排名关键词的部署方法_乐云SEO
- 怎么定位门面位置_如何选择店面位置
- JDBC数据库连接测试工具
- AI绘图参数设置和一些注意点
- 用 C++ 在Windows中清空回收站内文件/隐藏和显示桌面图标 / Windows任务栏 / 任务栏时钟 / 更改桌面壁纸
- 计算机应用基础(专)【10】
- python怎么输出所有奇数_python输出100以内奇数的几种输出方式-Go语言中文社区