浅谈:JVM垃圾回收

news2024/11/26 12:38:40

一、四种类加载器(双亲委托/全盘委托机制)

1.启动类加载器: 加载 Java 核心类库,无法被 Java 程序直接引用。
2.扩展类加载器: 加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
3.系统类加载器: 它根据 Java 应用的类路径(classpath)来加载 Java 类,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader() 来获取。
4.用户自定义类加载器: 通过继承java.lang.ClassLoader类的方式实现。

二、JVM内存模型

堆:

老年代(Old)占2/3,
年轻代(Young)占1/3,
年轻代包含Eden区和Survivor区,Survivor区包含From(S0区)区和To(S1区),默认Eden区、From区、To区的比例为8:1:1,
当Eden区内存不足时会触发Minor gc,没有被回收的对象进入到Survivor区,同时分代年龄+1,
再次触发Minor gc时,From区中的对象会移动到To区,Minor gc会回收Eden区和From区中的垃圾对象,对象的分代年龄会再次增加,
当分代年龄增加到15以后,对象会进入到老年代。当老年代内存不足时,会触发Full gc,
如果Full gc无法释放足够的空间,会触发OOM内存溢出,在进行Minor gc或Full gc时,会触发STW(Stop The World)即停止用户线程。

非堆(永久代/元空间区):

常量(final修饰)、静态变量(static修饰)、类信信息(版本、字段等)、运行时常量池,操作的是直接内存。 

三、JVM运行时数据区

1.程序计数器

 存放下一条指令所在单元的地址的地方。

2.线程栈(虚拟机栈)

JVM的每一个线程对应一个线程栈,一个线程的每个方法会分配一块栈帧内存空间。栈帧超过了栈的深度,会报StackOverflowError。
局部变量表:  存储基本数据类型(int、float、byte等),如果是引用数据类型,则存储的是其在堆中的内存地址,也就是指向对象的一个指针。
操作数栈:  主要用来存计算过程的中间结果,计算过程中变量临时的存储空间。CPU会从操作数栈中弹出所需的操作数,计算后压入到操作数栈顶。
i++ 和 ++i 的区别:
1、i++: 从局部变量表取出 i 并压入操作栈(load memory),对局部变量表中的 i 自增 1(add&store memory),将操作栈栈顶值取出使用,如此线程从操作栈读到的是自增之前的值。
2、++i: 先对局部变量表的 i 自增 1(load memory&add&store memory),然后取出并压入操作栈(load memory),再将操作栈栈顶值取出使用,线程从操作栈读到的是自增之后的值。
i++ 不是原子操作, 1、i 从局部变量表(内存)取出,2、压入操作栈(寄存器),操作栈中自增,3、使用栈顶值更新局部变量表(寄存器更新写入内存),这3步可能被另一个线程打断,产生数据互相覆盖问题。
动态链接:  在Java源文件被编译成字节码文件时,所有的变量和方法引用都作为符号引用存到class文件的常量池中。通过常量池中指向方法的符号引用来表示一个方法调用了其他方法时。动态链接是将符号引用转换为直接引用。
方法出口:  
方法执行时有两种退出情况:
    1.正常退出,即正常执行到任何方法的返回字节码指令,如 return、ireturn、areturn 等;
    2.异常退出。
方法退出就返回至方法当前被调用的位置。
    1.返回值压入上层调用栈帧。
    2.异常信息抛给能够处理的栈帧。
    3.PC计数器指向方法调用后的下一条指令。

3.本地方法栈

与虚拟机栈结构一致,本地方法栈执行的是Java底层由C++编写的native方法。

4.元空间

JDK1.8用元空间代替永久代,元空间是方法区的实现,用来存放常量(final修饰)、静态变量(static修饰)以及类的类的版本、字段、方法、接口等
该部分的内存默认情况下是off heap的(堆的一个逻辑分区)内存,大小不受jvm大小的限制,属于操作系统内存。

5.堆

堆是JVM所管理内存的最大一部分,在虚拟机启动时启动。
对象实例和数组都在堆上分配。堆内存不足,也会报OutOfMemoryError

三、JVM垃圾回收(GC)

1. 判定堆中对象是否为垃圾

引用计数法: 在对象中添加一个引用计数器,当有地方引用这个对象时,引用计数器值+1,当引用失效时,计数器值-1。两个对象循环引用的时,各自的计数器始终不会变成0,导致无法回收,引起内存泄露。(一般不采用)。
可达性分析法: 从GCRoots的对象(虚拟机栈、方法区的类属性引用的对象、方法区中常量引用的对象、本地方法栈中引用的对象)的引用连来判断是否为垃圾。

2.回收算法

标记–清除: 首先通过根节点,标记所有从根节点开始的可达对象。清除阶段,清除所有未被标记的对象。
标记–整理(压缩): 标记-压缩算法从根节点开始,对所有可达对象做一次标记。将所有的存活对象压缩到内存的一端,清理边界外所有的空间。
标记-复制: 将内存区域均分为了两块(记为S0和S1),创建对象的时只用其中的一块(如S0),当S0使用完之后,将S0上面存活的对象全复制到S1上去,然后将S0全部清理掉。

新生代中: 每次收集都会有大量对象死去,只要复制少量对象以及更改引用,所以可以选择复制算法。
老年代中: 没有额外的空间对它进行分配担保,因此选择标记清除或标记整理算法进行垃圾收集。

垃圾收集器

垃圾收集器工作方式作用空间     算法  特点适用场景
Serial
串行
新生代
复制算法
响应速度优先
适用于单CPU环境下的client模式
ParNew
并行
新生代
复制算法
响应速度优先
多CPU环境Server模式下与CMS配合使用
Parallel
并行
新生代
复制算法
吞吐量优先
适用于后台运算而不需要太多交互的场景
Serial Old
串行
老年代
标记-整理(压缩)算法
响应速度优先
适用于单CPU环境下的Client模式
Paraller Old
并行
老年代
标记-整理(压缩)算法
吞吐量优先
适用于后台运算而不需要太多交互的场景
CMS
并发
老年代
标记-清除算法
响应速度优先
适用于互联网或B/S业务
G1
并发、并行
新生代、老年代
标记-整理(压缩)算法
响应速度优先
响应速度优先

3.JVM调优

JVM 提供的常用工具
jconsole(bin目录下):用于对 JVM 中的内存、线程和类等进行监控的视图监控工具;
jvisualvm(bin目录下):JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等的视图监控工具。
jps:用来显示本地的 Java 进程,可以查看本地运行着几个 Java 程序,并显示他们的进程号。命令格式:jps.
jinfo:运行环境参数:Java System 属性和 JVM 命令行参数,Java class path 等信息。命令格式:jinfo 进程 pid.
jstat:监视虚拟机各种运行状态信息的命令行工具。命令格式:jstat -gc 123 250 20.
jstack:可以观察到 JVM 中当前所有线程的运行情况和线程当前状态。命令格式:jstack 进程 pid.
jmap:观察运行中的 JVM 物理内存的占用情况(如:产生哪些对象,及其数量)。命令格式:jmap [option] pid.

4.JVM 参数

参数        说明                实例
-Xms    初始堆大小,默认物理内存的1/64    -Xms512M
-Xmx    最大堆大小,默认物理内存的1/4    -Xms2G
-Xmn    新生代内存大小,官方推荐为整个堆的3/8    -Xmn512M
-Xss    线程堆栈大小,jdk1.5及之后默认1M,之前默认256k    -Xss512k
-XX:NewRatio=n    设置新生代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4    -XX:NewRatio=3
-XX:SurvivorRatio=n    年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:8,表示Eden:Survivor=8:1:1,一个Survivor区占整个年轻代的1/8    -XX:SurvivorRatio=8
-XX:PermSize=n    永久代初始值,默认为物理内存的1/64    -XX:PermSize=128M
-XX:MaxPermSize=n    永久代最大值,默认为物理内存的1/4    -XX:MaxPermSize=256M
-verbose:class    在控制台打印类加载信息
-verbose:gc    在控制台打印垃圾回收日志
-XX:+PrintGC    打印GC日志,内容简单
-XX:+PrintGCDetails    打印GC日志,内容详细
-XX:+PrintGCDateStamps    在GC日志中添加时间戳
-Xloggc:filename    指定gc日志路径    -Xloggc:/data/jvm/gc.log
-XX:+UseSerialGC    年轻代设置串行收集器Serial
-XX:+UseParallelGC    年轻代设置并行收集器Parallel Scavenge
-XX:ParallelGCThreads=n    设置Parallel Scavenge收集时使用的CPU数。并行收集线程数。    -XX:ParallelGCThreads=4
-XX:MaxGCPauseMillis=n    设置Parallel Scavenge回收的最大时间(毫秒)    -XX:MaxGCPauseMillis=100
-XX:GCTimeRatio=n    设置Parallel Scavenge垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)    -XX:GCTimeRatio=19
-XX:+UseParallelOldGC    设置老年代为并行收集器ParallelOld收集器
-XX:+UseConcMarkSweepGC    设置老年代并发收集器CMS
-XX:+CMSIncrementalMode    设置CMS收集器为增量模式,适用于单CPU情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

seleniumUI自动化登录失败案例重新尝试WhileTrue

一个用户每次登录失败,失败N次,无法进入下一url时,怎样会重新尝试N次重新登录呢 ? 我们可以使用wihile true判断,并使用currenturl判断,下面就介绍以下个人的方法 currenturlEGTconfigFile.driver.curren…

Opencv识别车牌

Opencv识别车牌 #encoding:utf8 import cv2 import numpy as np Min_Area 50 #定位车牌 def color_position(img,output_path): colors [#([26,43,46], [34,255,255]), # 黄色 ([100,43,46], [124,255,255]), # 蓝色 ([35, 43, 46], [77, 255, 255]) # 绿色 ] hsv cv2.cvtCo…

推荐 7 个超牛的 Spring Cloud 实战项目

个 把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,这就是微服务架构的架构概念,通过将功能分解到各个离散的服务中以实现对解决方案的解耦。 关于微服务相关的学习资料不多,而 GitHub 上的开源项目可以作为你微服务之旅…

STM32平衡小车 mpu6050学习

MPU6050简介 MPU6050是一款性价比很高的陀螺仪,可以读取X Y Z 三轴角度,X Y Z 三轴加速度,还有内置的温度传感器,在姿态解析方面应用非常广泛。 二、硬件连接 由于采用IIC通信,最基本的只需要采用四根线就可以了。分别VCC,GND,SCL,SDA连接到单片机 SCL-----PB6 SDA---…

23种设计模式之观察者模式(黑马程序员)

观察者模式 一、概述二、结构三、实现四、总结在最后 一、概述 观察者模式又被称为发布-订阅模式(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有…

java 键值对详解及java键值对代码

在 Java中,对象可以理解为一个列表。这个列表里面的每个元素都是一个“键”,而每个“键”都是一个值。 键值对的概念,并不是在 Java中第一次出现,在 java 1.x中就已经有了。那时候它的意思是在一个命名空间中建立两个名字相同的对…

利用三维CNN对阿尔茨海默病进行多模态研究

文章目录 Is a PET All You Need? A Multi-modal Study for Alzheimer’s Disease Using 3D CNNs摘要方法实验结果讨论结论 Is a PET All You Need? A Multi-modal Study for Alzheimer’s Disease Using 3D CNNs 摘要 提出了一个系统评估多模态dnn的框架重新评估基于FDG-P…

Android-实现一个登录页面(kotlin)

准备工作 首先,确保你已经安装了 Android Studio。如果还没有安装,请访问 Android Studio 官网 下载并安装。 前提条件 - 安装并配置好 Android Studio Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built …

如何使用命令行添加配置码云仓库SSH秘钥-git仓库也一样

使用命令行添加配置码云仓库SSH秘钥 为什么要如何使用命令行添加配置码云仓库SSH秘钥?生成密钥你可以按如下命令来生成 sshkey:可以参考下图执行指令 添加密钥登录你的码云,鼠标移入头像,设置。点击 SSH公钥,打开配置页面&#x…

新型数字智慧城市综合趋势解决方案(ppt可编辑)

本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除 新型智慧城市解决方案总体架构 新型智慧城市顶层规划(咨询)服务概述 服务定义:提供面向城市及其产业的智慧化咨询服务,涵盖需求…

linux——进程的概念与状态

大家好,我是旗帜僵尸。今天我将带领大家学习进程的概念。 本篇文章将继续收录于我的linux专栏中,若想查看关于linux其它知识的文章也可以点击右方链接。旗帜僵尸——linux 文章目录 一、进程概念冯诺依曼体系结构OS(操作系统Operator System&…

突破传统监测模式:业务状态监控HM的新思路

作者:京东保险 管顺利 一、传统监控系统的盲区,如何打造业务状态监控。 在系统架构设计中非常重要的一环是要做数据监控和数据最终一致性,关于一致性的补偿,已经由算法部的大佬总结过就不在赘述。这里主要讲如何去补偿&#xff…

电子阅读器市场角力,AI成为关键变量

配图来自Canva可画 近年来,随着国家“书香型社会”建设政策的出台,公众的阅读需求正在逐年增加,各类读书产品和读书活动,也如同雨后春笋般涌现,人们的阅读体验日益得到丰富。比如,昨天世界读书日举行的“不…

Photoshop在启动时出现读取计算机特定首选项时出错,或者提示暂存盘已满导致打不开该如何处理

上午还能用,下午打开Photoshop时就报此错误 点击确定后,出现下图错误 首先,先试试删除设置文件。在长按shiftctrlalt的情况下用鼠标右键点击Photoshop图标,点击打开(此间别松手),就会出现下图&a…

“智慧赋能 强链塑链”|工程物资供应链管理中的数字化应用

工程项目中的供应链管理至关重要 工程建设行业是国民经济的重要支柱之一,虽然在总产值上持续保持增长态势,但近年来行业的利润总额增速已连续多年呈现下降趋势。究其原因,可以大体从两个方面来看:一是行业盈利能力出现下降&#x…

Xshell CentOs Linux命令2

上一次我们说了几个命令,文件的创建删除等,还有就是文件查看,今天我们继续看几个命令。 echo echo命令 我们看到我们在echo 后面跟一个字符串,不同会帮我们打印在屏幕上,这里我们需要补充一些东西,在Linu…

多线程常见的锁策略

目录 1.1 乐观锁 和 悲观锁 1.2 轻量级锁 和 重量级锁 1.3 自旋锁 和 挂起等待锁 1.4 互斥锁 和 读写锁 1.5 可重入锁 和 不可重入锁 1.6 公平锁 和 非公平锁 1.7 synchronized 锁的属性 一、锁策略 说到锁,Java 里面常用的锁有 synchronized ,锁…

安全防御 --- 态势感知、VPN

一、态势感知 1、概念 态势感知(SA --- Situational Awareness)是对一定时间和空间内的环境元素进行感知,并对这个元素的含义进行理解,最终预测这些元素在未来的发展状态。 作用: 态势感知能够检测出超过20大类的云上…

使用nvm(node.js version management)安装管理nodejs

鉴于目前网络上关于NVM安装NodeJS操作步骤的文章,大家都在互相借鉴,很少看到原创文章,很多操作步骤已经冗余和过时。因此,本人根据实际的前端项目开发经验,在此重新梳理了一遍目前最新的NVMNodeJS的安装步骤&#xff0…

微信小程序原生开发功能合集十二:编辑界面的实现

本章实现编辑界面的实现处理,包括各编辑组件的使用及添加数据保存数据流程的实现处理。   另外还提供小程序开发基础知识讲解课程,包括小程序开发基础知识、组件封装、常用接口组件使用及常用功能实现等内容,具体如下:    1. CSDN课程: https://edu.csdn.net/course/…