前言

抛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内存模型是:

  1. 每一秒产生60M对象,均放到eden区

  2. 到第13秒时,eden区内存即将占满(60*13 =780M),触发minor gc

  3. 这时候会对前12秒的对象进行回收,第13秒产生的对象由于还在执行,因此判断为有效对象,会被移动到S0区

  4. 这时候会触发jvm另外一个机制--动态年龄判断,即发现该对象大小大于survivor区内存大小的50%,会直接进入old区。因此该60M对象会直接移动到old区。因此会出现每过13秒,会有60M数据进入old区

  5. 所以old区大概多久会被占满,2000M/60 *13 = 433s。也就是大概433s后就会触发一次full gc

  6. 因此问题来了,如果这个大促持续数个小时,而每隔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原理和调优(读这一篇就够了)相关推荐

  1. JVM原理及调优--网页链接收藏

    此篇用于收藏大神们关于JVM原理及调优通俗易懂的文章链接,用于随时查看 JVM调优总结 JVM参数配置大全 JVM调优:选择合适的GC collector 菜菜鸟想了解下大概的JVM内存模型可以看这个 ...

  2. JVM原理和调优的理解和学习

    JVM原理和调优的理解和学习 一.详解JVM内存模型 二.JVM中一次完整的GC流程是怎样的 三.GC垃圾回收的算法有哪些 四.简单说说你了解的类加载器 五.双亲委派机制是什么,有什么好处,怎么打破 ...

  3. JVM原理、调优、GC

    转自:https://www.jianshu.com/p/63fe09fe1a60 jvm原理 Java虚拟机是整个java平台的基石,是java技术实现硬件无关和操作系统无关的关键环节,是java语 ...

  4. win7查看tomcat端口_想研究Tomcat性能调优,看这篇就够了

    一.下载地址 https://tomcat.apache.org/download-80.cgi 二.安装步骤 将安装包 apache-tomcat-8.5.39.tar.gz 上传至服务器 /usr ...

  5. 一篇最通俗易懂的性能调优总结,这篇就够了

    一,什么是性能调优? 在说什么是性能调优之前,我们先来说一下,计算机的体系结构. 如上图,简单来说包括三块:硬件.操作系统.应用程序.其实,性能调优就是调节这些内容,包括硬件.操作系统.应用程序.其中 ...

  6. java虚拟机工作原理图_超“强”的图文详解-JVM虚拟机底层原理与调优实战

    今天我和大家分享一篇文章,文章上半部分为JVM底层原理 下半部分为调优实战 文章有点长,需要点耐心哦! 如果觉得看文章太难理解,就点击下面我投稿B站的jvm视频讲解. 还配有视频讲解:解密BATJ一线 ...

  7. 全面的GC原理及调优

    本文介绍 GC 基础原理和理论,GC 调优方法思路和方法,基于 Hotspot jdk1.8,学习之后你将了解如何对生产系统出现的 GC 问题进行排查解决. 图片来自 Pexels 内容主要如下: G ...

  8. 第二十一期:老大难的GC原理及调优,这全说清楚了

    本文介绍 GC 基础原理和理论,GC 调优方法思路和方法,基于 Hotspot jdk1.8,学习之后你将了解如何对生产系统出现的 GC 问题进行排查解决. 本文介绍 GC 基础原理和理论,GC 调优 ...

  9. 老大难的GC原理及调优,这下全说清楚了

    " 本文介绍 GC 基础原理和理论,GC 调优方法思路和方法,基于 Hotspot jdk1.8,学习之后你将了解如何对生产系统出现的 GC 问题进行排查解决. 文章转载自51CTO技术栈 ...

最新文章

  1. python基础之python中if __name__ == '__main__': 的解析
  2. JAVA——基于HttpClient的通过单点登录方式(统一身份认证平台)登录正方教务系统[1999-2020]基本解决方案
  3. jsr133-第一二章
  4. 64位ubuntu kylin 16.04下制作tiny4412可用的SD启动卡
  5. adb shell 书籍_开发必备---你应该知道的一些 ADB 命令
  6. 技术人生:希望有生之年开发一个“自己的解释语言”
  7. Mybatis之执行自定义SQL举例
  8. 华为手机芯片断供,有没有可能回收旧手机解决目前困境?
  9. bxl类型封装转换为AD库封装
  10. Ttest + 秩和检验
  11. C语言写的一个贪吃蛇小游戏(windows系统)
  12. 梦行扫码付(收银台条码支付 微信钱包条码支付 支付宝二维码支付 手机APP钱包支付 PHP扫码支付 )
  13. 全国计算机三级答案,全国计算机三级数据库技术笔试试题(附正确答案)
  14. 搜索引擎排名都选乐云seo_乐云百度爱采购排名关键词的部署方法_乐云SEO
  15. 怎么定位门面位置_如何选择店面位置
  16. JDBC数据库连接测试工具
  17. AI绘图参数设置和一些注意点
  18. 用 C++ 在Windows中清空回收站内文件/隐藏和显示桌面图标 / Windows任务栏 / 任务栏时钟 / 更改桌面壁纸
  19. 计算机应用基础(专)【10】
  20. python怎么输出所有奇数_python输出100以内奇数的几种输出方式-Go语言中文社区

热门文章

  1. 最简单DIY基于ESP32CAM的物联网相机系统⑤(用1306OLED实现WIFI黑白屏照相机)
  2. Hexo+yilia添加helper-live2d插件实现宠物动画
  3. 电视支架什么牌好?电视支架品牌推荐
  4. Moe Wallpaper 桌面动态壁纸设置器V2.3
  5. Mathway:对付数学作业的新武器
  6. Multi Paxos
  7. 推荐几个不错的 CSS 工具,持续收录!
  8. 视频编解码相关资料汇总
  9. Java如何获取当前项目路径
  10. 开机按F8键进入安全模式的菜单含义全解