首页 > 其他分享 >JVM基础

JVM基础

时间:2023-09-27 09:11:53浏览次数:40  
标签:G1 对象 基础 STW GC 内存 JVM CMS

欢迎参观我的博客,一个Vue 与 SpringBoot结合的产物:https://poetize.cn

原文链接:https://poetize.cn/article?id=7

Java堆

从回收内存的角度看

  • Java 堆,由年轻代和年老代组成,分别占据 1/3 和 2/3。
  • 而年轻代又分为三部分,Eden、From Survivor、To Survivor,占据比例为 8:1:1,可调。

对象的创建

  • 类加载
  • 内存分配:1,指针碰撞(复制算法/标记-整理算法);2,空闲列表(标记-清除算法)
  • 初始化零值
  • 设置对象头
  • init方法

类加载过程

  • 加载:通过全限定类名加载类型数据到元空间,并在堆中生成一个代表这个类的Class对象,作为访问类型数据的外部接口。
  • 验证
  • 准备:给静态变量分配内存并设置类变量初始值的阶段。
  • 解析符号引用转为直接引用
  • 初始化:为静态变量赋代码编写的值

对象的回收

可达性算法

  • 静态变量,常量
  • 执行上下文(方法栈帧中局部对象引用)

垃圾收集器

新生代

  • Serial:复制,单线程,STW
  • ParNew:复制:多线程,STW
  • Parallel Scavenge:复制,多线程,STW,吞吐量优先收集器
  • G1

老年代

  • Serial Old:标记整理,单线程,STW
  • Parallel Old:标记整理,多线程,STW,吞吐量优先收集器
  • CMS:标记清除,并发低停顿内存碎片较多依赖CPU资源浮动垃圾
    • 初始标记:单线程,STW
    • 并发标记
    • 重新标记:多线程,STW
    • 并发清除
  • G1

CMS与G1

CMS会导致碎片化,大对象会频繁触发FullGC,FullGC意味着完全的STW,应用线程彻底停止,直到完成对堆的清理。堆越大FullGC停顿的时间就越长。

CMS垃圾回收器不能满足性能需求,而G1相比CMS有更清晰的优势:

  1. CMS没有采用复制算法,所以它不能压缩,最终导致内存碎片化问题。而G1采用了复制算法,它通过把对象从若干个Region拷贝到新的Region过程中,执行了压缩处理。

  2. CMS必须扫描整个堆来确认存活对象,所以,长时间停顿是非常常见的。而G1的停顿时间取决于收集的Region集合数量,而不是整个堆的大小,所以相比起CMS,长时间停顿要少很多,可控很多。

选择合适的垃圾回收器

  • CPU单核,那么毫无疑问Serial 垃圾收集器是你唯一的选择。
  • CPU多核,关注吞吐量 ,那么选择PS+PO组合。
  • CPU多核,关注用户停顿时间,JDK版本1.6或者1.7,那么选择CMS。
  • CPU多核,关注用户停顿时间,JDK1.8及以上,JVM可用内存6G以上,那么选择G1。

JVM 调优

1. 网站流量暴增后反应很慢

  1. 推测:垃圾收集导致业务线程停顿
  2. 定位:jstat -gc发现GC频率过高
  3. 解决:加大内存
  4. 第二个问题:加大内存后单次卡顿变长
  5. 解决:JDK1.8默认垃圾收集器Parallel Scavenge + Parallel Old,增大内存后停顿时间就变长了。可以使用CMS,并设置了一个预期的停顿时间。

2. OOM

-XX:+HeapDumpOnOutOfMemoryError参数获得堆内存的dump文件。

3. 内存飙高

1、先观察垃圾回收的情况

  • jstat -gc PID 1000查看GC次数,时间等信息,每隔一秒打印一次。
  • jmap -histo PID | head -20查看堆内存占用空间最大的前20个对象类型,可初步查看是哪个对象占用了内存。

如果每次GC次数频繁,而且每次回收的内存空间也正常,那说明是因为对象创建速度快导致内存一直占用很高;
如果每次回收的内存非常少,那么很可能是因为内存泄露导致内存一直无法被回收。

2、导出堆内存文件快照

  • jmap -dump:live,format=b,file=/home/myheapdump.hprof PIDdump堆内存信息到文件。

4. 频繁Full GC

通过jstat命令发现系统每次Young GC后大约有10%的存活对象进入老年代。

原来是因为Survivor区空间设置过小,每次Young GC后存活对象在Survivor区域放不下,提前进入老年代。

通过调大Survivor区,使得Survivor区可以容纳Young GC后存活对象,对象在Survivor区经历多次Young GC达到年龄阈值才进入老年代。

标签:G1,对象,基础,STW,GC,内存,JVM,CMS
From: https://www.cnblogs.com/loveer/p/17731806.html

相关文章

  • JavaSE day01【复习回顾面向对象基础、继承、抽象类】测评
    选择题题目1(单选):下列关于Java中类与类之间的关系描述正确的是()选项:​ A.Java中类与类属于多继承,还可以多层继承​ B.Java中类与类属于实现关系,可以单实现也可以多实现​ C.Java中类与类属于实现关系,可以只能单实现​ D.Java中类与类属于单继承,......
  • ansible基础
    语法:1.添加主机或者主机组:[root@ansible-server~]#vim/etc/ansible/hosts #在最后追加被管理端的机器ansible-web1           #单独指定主机,可以使用主机名称或IP地址2.添加主机组:[webservers]    #使用[]标签指定主机组----标签自定义......
  • 信息系统基础知识
    信息的定义香农在《通信的数学理论》一文中对“信息”的理解是“不确定性的减少”,由此引申出信息的一个定义:“信息是系统有序程度的度量”。该定义给出了信息的定量描述,并确定了信息量的单位为“位”。一位的信息量,在变异度为2的最简单情况下,就是能消除非此即彼的不确定性所需要的......
  • neovim入门指南(一):基础配置
    文章首发https://youngxhui.top在编程的世界中,有两个上古神器。一个叫做“神之编辑器Emacs”,另一个叫做“编辑器之神vim”。这两个编辑器从诞生到现在,圣战从未结束。无论是vim还是emacs都在不断的进化和发展,渐渐的vim的分支上出现了一颗夺目的新星,他就是neovim。什......
  • CH9141基础应用篇
    原文链接:https://www.cnblogs.com/risc5-ble/p/16397743.htmlCH9141使用十分方便,是一款蓝牙串口透传芯片,无需二次开发,可以直接使用的,支持三种模式:从机模式,主机模式,广播模式。对于模块刚拿到手的小伙伴可以先接上这几根线:1.购买带底板的豪友们,使用杜邦线将模块与CH340连接(VCC,GN......
  • 唐老狮Unity基础笔记
    唐老狮Unity基础笔记三角函数Mathf.Rad2DegMathf.Deg2Rad 坐标系 向量    ......
  • C#基础 - Task
    目录前言1,Task的分类2,Task的状态2.1TaskStatus枚举2.2状态相关属性2.3小结3,Task的等待3.1Wait方法3.2死锁3.2.1死锁形成3.3.2死锁避免4,Task的结果4.1Result4.2GetAwaiter().GetResult()4.3await关键字5,Task的继续5.1ContinueWith方法5.2其他方法6,Task的启动6.1Start......
  • CS101-计算机科学基础名词解释
    Turingmachine:图灵机理论上可以计算任何东西CPU(CenterProcessUnit):中央处理器是现代电脑的“大脑”,其中包含数十亿细小开关的硅片,即晶体管Transistors:晶体管每个开关代表一个“位”Bit:位是电脑能够识别的最小信息Byte:字节每8个位一组,称为一个字节ASCI......
  • jvm工作原理
    加载:JVM在启动时会加载Java类的字节码文件(.class文件),将这些字节码加载到内存中。验证:JVM会验证加载的字节码是否符合Java虚拟机规范,确保字节码的安全性。准备:JVM会为类的静态变量分配内存,并设置初始值。解析:JVM会将字节码转换为Java虚拟机内部的数据结构,如......
  • Vue3 组件基础:轻松掌握前端开发新技能!
    基本实例这里有一个Vue组件的示例://创建一个Vue应用constapp=Vue.createApp({})//定义一个名为button-counter的新全局组件app.component('button-counter',{data(){return{count:0}},template:`<button@click="count++">......