JVM-内存划分-垃圾回收器-回收算法-双亲委派-三色标记

简介: JVM-内存划分-垃圾回收器-回收算法-双亲委派-三色标记

四、JVM

1.JVM内存结构

虚拟机栈:每次调用方法都会产生一个栈帧,每个栈帧中有方法的参数、局部变量、放出出口等信息,方法执行完成之后释放栈帧,每个线程都有自己的虚拟机栈,是线程私有的

本地方法栈:一些带有 native 关键字的方法就是需要 JAVA 去调用本地的C或者C++方法,因为 JAVA 有时候没法直接和操作系统底层交互,所以需要用到本地方法栈,服务于带 native 关键字的方法。为本地方法调用提供内存空间

程序计数器:记录下一条指令的地址,可以自增,通过寄存器实现,唯一不会内存溢出的地方,线程私有

问题辨析:

垃圾回收是否涉及栈内存?

不会。栈内存是方法调用产生的,方法调用结束后会弹出栈(自动回收)。

栈内存分配越大越好吗?

不是。因为物理内存是一定的,栈内存越大,可以支持更多的递归调用,但是可执行的线程数就会越少。非windows默认1mb,windows动态分配

如果方法内部的变量没有逃离方法的作用访问,它是线程安全的,因为每个线程有自己的栈。

如果是局部变量引用了对象,并逃离了方法的访问(有返回值是存在安全问题的),那就要考虑线程安全问题。

一句话。私有线程安全,共享不安全

:JVM回收的主要区域,存放对象信息,分为新生代和老年代,新生代的eden取内存不够发送MinorGC,老年代内存不够发送FullGC

通过new关键字创建对象使用堆内存

线程共享,考虑线程安全问题

有垃圾回收机制(gc)

方法区:Java 虚拟机有一个在所有 Java 虚拟机线程之间共享的方法区域。方法区域类似于用于传统语言的编译代码的存储区域,或者类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括特殊方法,用于类和实例初始化以及接口初始化,方法区域是在虚拟机启动时创建的。尽管方法区域在逻辑上是堆的一部分,但简单的实现可能不会选择垃圾收集或压缩它。此规范不强制指定方法区的位置或用于管理已编译代码的策略。方法区域可以具有固定的大小,或者可以根据计算的需要进行扩展,并且如果不需要更大的方法区域,则可以收缩。方法区域的内存不需要是连续的!JDK1.7采用持久代实现,1.8使用元空间实现

2.JVM的垃圾回收算法

  1. 标记清除:标记不需要回收的对象,然后清楚没有标记的对象,会造成大量内存碎片
  2. 标记整理:和标记清楚类似,标记之后,将存活对象向一端移动,清楚边界外的垃圾对象,标记清楚和整理由垃圾回收期决定使用哪一种,用在老年代
  3. 复制算法:内存一分为二,只使用一块,gc时将活着的对象移动带另一块,然后清空之前的区域,用在新生代的eden区和survice区

3.如何判断对象是否可以回收

引用计数法:已经淘汰,每个对象添加引用计数器,引用为0可以回收,互相引用无法回收

可达性分析算法:从GCRoot开始搜索,搜索过的路径称为引用链,若一个对象没有任何引用链,判定为可以回收

GCRoot:虚拟机栈中引用的对象,方法区中静态变量引用的对象,方法区中常量引用的对象,Native方法中JNI引用的对象

4.典型的垃圾回收器

CMS:最小停顿时间为目标,只运行在老年代的回收器,使用标记整理算法,可以并发收集

G1:JDK1.9后默认的垃圾回收期,注重响应速度,支持并发,使用标记整理+复制算法回收内存

5.双亲委派机制

向上委派,向下实现

中文名称 加载器 加载目录
核心类加载器 BootStrapClassLoader JAVA_HOME/jre/lib
扩展类加载器 ExtensionClassLoader JAVA_HOME/jre/lib/ext
应用程序类加载器 ApplicationClassLoader classpath

当有一个类被加载请求时,先将请求交给父类加载器,父类记载器找不到该类就向下去找,避免重复加载和系统级别的类被篡改

6.JVM的四种引用和回收时机

强引用:new的对象,只有所有的gc root对象都不能通过【强引用】引用该对象才能被回收

软引用:在垃圾回收后,内存不足时会再次发出垃圾回收,回收软引用对象

弱引用:每次垃圾回收都会回收

虚引用:必须配合引用队列使用,主要配合ByteBuffer使用,被引用对象回收时,会被虚拟机放入引用队列

7.类加载过程

(1)加载:将字节码通过二进制的方式转化到方法区中的运行数据区

(2)连接:

验证:验证字节码文件的正确性

准备:正式为类变量在方法区中分配内存,并设置初始值,final类型在编译期间赋值

解析:将常量池的符号引用(类的全限定名)解析为直接引用(类在实际内存中的地址)

(3)初始化:执行类构造器,为静态变量赋初始值并初始化静态代码块

8.JVM调优参数

-Xmx[]:堆内存最大内存

-Xms[]:堆内存最小内存,一般设置成跟堆空间最大内存一样的

-Xmn[]:新生代的最大内存

-xx:[survivorRatio=3]:eden区与from+to区的比例为3:1,默认为4:1

-xx[use 垃圾回收器名称]:指定垃圾回收器

-xss:设置单个线程栈大小

一般设堆空间为最大可用物理地址的百分之80

9.三色标记以及漏标问题

三色标记是cms和g1收集器的垃圾追踪方法

黑色对象:自己和引用的对象完全扫描

灰色对象:扫描了本身没有扫描全部对象

白色对象:没有扫描的对象

漏标的充要条件:

黑色对象标记之后引用了白色对象

黑色对象引用的灰色对象在自己扫描之后删除了白色对象的引用

那么就漏标了白色对象会意外删除

cms采用增量更新,破坏第一个条件,黑色对象引用白色对象之后将引用记录下来,最后标记的时候对黑色对象重新扫描

G1采用原始快照,破坏第二个条件,取消白色引用之前将引用记录下来,最后标记的时候对白色对象扫描

10. G1收集器原理

jdk1.9之后的默认收集器,保持高回收率减少停顿,每次只清理一部分,保证停顿时间不会过长

取消了新生代和老年代的物理划分,将堆分为若干个逻辑区域region,一部分作为新生代一部分作为老年代,还有一部分存储大对象,

同CMS相同,会遍历所有对象,标记引用情况,清除对象后会对区域进行复制移动,以整合碎片空间.

11. ZGC收集器原理

前面提供的高效垃圾回收算法,针对大堆内存设计,可以处理TB级别的堆,可以做到

10ms以下的回收停顿时间

着色指针

读屏障

并发处理

基于region

内存压缩(整理)

roots标记:标记root对象,会StopTheWorld.

并发标记:利用读屏障与应用线程一起运行标记,可能会发生StopTheWorld. 清除会清理标记为不可用的对象.

roots重定位:是对存活的对象进行移动,以腾出大块内存空间,减少碎片产生.重定位最开始会StopTheWorld,却决于重定位集与对象总活动集的比例.

并发重定位与并发标记类似.

流程还是同cms类似

12. 简述java对象结构

java对象由三部分组成:对象头、实例数据、对齐填充

对象头:第一部分存储自身运行时数据:哈希码、gc分代年龄、锁标识、线程持有的锁、偏向锁id,第二部分是指针类型,指向对象的类元数据类型

实例数据:存储真正的有效信息,包括父类继承下来的和自己定义的

对齐填充:JVM要求对象起始地址必须是8字节的整数倍,(8字节对齐)

13. jvm调优命名

jps:显示系统内所有的虚拟机进程

jstat:是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

jmap:用于生成heap dump文件

jhat:与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看

jstack:用于生成java虚拟机当前时刻的线程快照。

jinfo:命令作用是实时查看和调整虚拟机运行参数。

14.逃逸分析 栈上分配 标量替换 方法内联

逃逸分析是优化内存分配的一种手段

方法逃逸:在一个方法体内,定义一个局部变量,而它可能被外部方法引用,比如作为调用参数传递给方法,或作为对象直接返回。或者,可以理解成对象跳出了方法。那么我们就无从知道哪些地方会使用这个变量。

线程逃逸:这个对象被其他线程访问到,比如赋值给了实例变量,并被其他线程访问到了。对象逃出了当前线程。

如果一个方法不会发生逃逸,那么可以在栈上分配内存,减少gc压力,

标量替换:基本数据类型不可分割称之为标量,可以分割的称之为聚合量,如果对象可分解,并且发生了逃逸,那么不会真正创建这个对象,会创建若干个成员变量来替换,拆散的变量可以单独分析与优化,在各自的栈上分配内存

方法内联

方法内联指的是在编译过程中遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。

相关文章
|
17天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
38 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
5天前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
6天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
16天前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
42 2
|
17天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
36 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
18天前
|
算法 Java
JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。
 JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
|
14天前
|
Java
JVM进阶调优系列(5)CMS回收器通俗演义一文讲透FullGC
本文介绍了JVM中CMS垃圾回收器对Full GC的优化,包括Stop the world的影响、Full GC触发条件、GC过程的四个阶段(初始标记、并发标记、重新标记、并发清理)及并发清理期间的Concurrent mode failure处理,并简述了GC roots的概念及其在GC中的作用。
|
15天前
|
存储 Kubernetes 架构师
阿里面试:JVM 锁内存 是怎么变化的? JVM 锁的膨胀过程 ?
尼恩,一位经验丰富的40岁老架构师,通过其读者交流群分享了一系列关于JVM锁的深度解析,包括偏向锁、轻量级锁、自旋锁和重量级锁的概念、内存结构变化及锁膨胀流程。这些内容不仅帮助群内的小伙伴们顺利通过了多家一线互联网企业的面试,还整理成了《尼恩Java面试宝典》等技术资料,助力更多开发者提升技术水平,实现职业逆袭。尼恩强调,掌握这些核心知识点不仅能提高面试成功率,还能在实际工作中更好地应对高并发场景下的性能优化问题。
|
17天前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
29 4
|
3月前
|
Java Docker 索引
记录一次索引未建立、继而引发一系列的问题、包含索引创建失败、虚拟机中JVM虚拟机内存满的情况
这篇文章记录了作者在分布式微服务项目中遇到的一系列问题,起因是商品服务检索接口测试失败,原因是Elasticsearch索引未找到。文章详细描述了解决过程中遇到的几个关键问题:分词器的安装、Elasticsearch内存溢出的处理,以及最终成功创建`gulimall_product`索引的步骤。作者还分享了使用Postman测试接口的经历,并强调了问题解决过程中遇到的挑战和所花费的时间。