首页 > 其他分享 >JVM虚拟机总结

JVM虚拟机总结

时间:2024-09-24 17:34:28浏览次数:1  
标签:总结 Java 标记 对象 虚拟机 收集器 算法 JVM

        读了周志明老师的《深入理解Java虚拟机:JVM高级特性与最佳实践》第三版,总结一下里面的知识点。一方面是知识储备更多一些,另外是也为接下来的面试准备一下。

        全书分为13个章节,共5部分内容。我着重是看了jvm的内管管理、垃圾收集与内存分配策略、虚拟机故障工具和调优实战、类加载机制、Java内存模型以及线程安全锁这几个章节,一方面这几个章节里面的知识点在实际的工作里面有所适用,另外一方面是这里面的知识点基本都是面试经常面到的。

         Java虚拟机把内存分为若干个不同的区域,包括程序计数器、虚拟机栈、本地方法栈、方法区和堆。方法区和堆属于所有线程共享的数据区,其他三个则是线程私有的。

         程序计数器:它是当前线程所执行的字节码的行号指示器,此区域是唯一一个不会出现OutofMemoryError的区域

         虚拟机栈:虚拟机栈是描述Java方法执行的线程内存模型:每个方法被执行时候,Java虚拟机都会创建一个栈帧,用户存储局部变量、操作数栈、动态链接、方法出口等信息。每个方法被调用直至执行完毕的过程,就对应的一个栈帧在虚拟机中从入栈到出栈的过程。如果线程请求的栈深度大于虚拟机所允许的深度,则会抛出StackOverflowError 异常

        本地方法栈:本地方法栈和虚拟机栈作用是类似的,区别是虚拟机栈是服务Java(也就是字节码),而本地方法栈是服务native方法的

        Java堆:对于Java程序来说,Java堆是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的区域,在虚拟机启动时创建,此区域的唯一目的就是存储对象。 接下来的基本都是在Java堆里面的操作,下面会在重点来说。当Java堆内存不足时候,虚拟机会抛出OutofMemoryError异常

        方法区:方法区也是线程共享的,主要是存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等

      了解了Java虚拟机的构成之后,接下来就是针对Java虚拟机的重点-Java堆来展开介绍了。Java里面有大量的对象,这些对象怎么在堆里面创建、回收、生命周期是怎么样的,这些都是Java堆的处理。

      在Java里面,创建一个对象是通过new的方式来创建的,创建之后Java堆为其分配好内存的大小,当该对象不在使用或者怎么知道该对象不在使用后,Java回收期会对该对象进行回收呢? Java虚拟机通过GcRoot算法和引用计数算法来确定一个对象是否需要进行回收。

     引用计数算法:在对象中添加一个引用计算器,每当有一个地方引用他时候,计数器加1,当引用失效时候,计数器减一。但其很难解决对象互相循环引用的问题

    可达性分析算法:这个算法的思路是通过一系列成为Gc Roots 的跟对象作为起始点合集,如果某个对象到Gc Roots没有任何的引用链相连,则认为此对象不在使用。

      当知道一个对象是否是出于要回收还是继续存活后,就可以对该对象进行垃圾回收了。虚拟机在对对象回收的过程中,使用了很多种垃圾回收器,随着计算机以及虚拟机的发展,垃圾回收器也纷繁多样,适用不同的场景。

     垃圾收集算法目前都是基于这几种方式为基础的:

     标记-清除算法(mark-sweep):算法分为标记和清除阶段,首先标记出所有需要回收的对象,在标记完成后,统一回收所有标记的对象。 该算法是最基础的收集算法,他的缺点主要有两个:第一个是执行效率不稳定,如果Java对象中含有大量的对象,而且其中大部分是需要回收的,这时会进行大量的标记和清除动作,导致标记和清除都会随着对象的数量增长执行效率的降低;第二个则是会产生内存空间碎片化问题,导致后面如果需要大对象分配时候,没有连续的内存空间而需要提前触发一次full gc

    标记-复制算法:将可用内存按照容量划分为大小相同的两块,每次只使用一块,当这一块使用完之后,将还存活的对象拷贝到另一块上面,然后把已使用过的内存空间进行一次清理。如果内存中多数对象都是存活的,这种算法将会产生大量的内存间复制的开销,但是对于少数的可回收的情况,则会很快,而且也没有空间碎片 。标记-复制算法的优缺点也很明显,优点是不会产生空间碎片,缺点则是内存的使用降低了

 标记-整理算法(mark-compact):由于标记-复制算法存在内存使用率不高的问题,以及当有大量的对象都存活时候,复制算法和清除算法都有一些效率的问题,因此针对老年代的对象的死亡特征,提出来了标记-整理算法。标记整理算法的标记部分,和标记-清除算法一样,但是比标记之后不在进行清理,还是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。这样的优点很明显,首先是内存空间不在存在碎片化的问题,其次是也没有浪费内存。但是也有缺点:就是整理时候的移动,这种对象移动的操作必须全程暂停用户的应用程序才行。也就是 stop-the-world. 基于标记整理和标记清除算法的优缺点,是否移动都会存在弊端:移动则内存回收更加复杂,不移动则存在空间碎片导致内存分配更加复杂,从垃圾回收的停顿时间来看,不移动对应垃圾回收的停顿时间更短,但是从整个程序的吞吐量来说,移动对象则更划算。

      基于以上几种垃圾回收的算法,出现了几个比较经典的垃圾收集器:从早期的Serial收集器,parNew/Parallel以及接下来的 cms/g1/,以及低延迟的 zgc/shenandoash收集器等。下面会介绍下每种收集器。

      Serial收集器:Serial收集器是历史最悠久,最基础的收集器。这个收集器是单线程收集器。新生代使用标记-复制算法,老年代使用标记-整理算法

      ParNew收集器:parNew收集器是Serial收集器的多线程版本,除了同时使用多条线程进行垃圾收集外,其他的 收集算法、stop the world、对象分配规则、回收策略等都和Serial收集器一样。

     Paralel Scavenge收集器: Paralel Scavenge也是一款新生代收集器,同样是基于标记=复制算法实现,也能并行收集的多线程收集器,和ParNew收集器很相似,但是它的目标是达到一个可控制吞吐量的收集器, 

           吞吐量 =  运行用户代码时间/(运营用户代码时间+垃圾回收收集时间)

     高吞吐量可以最高效率的利用服务器资源,尽快完成程序的运算任务。Paralel收集器会根据当前系统的允许情况,动态的调整以提供最合适的停顿时间或最大的吞吐量。这种方式称为垃圾收集的自适应的调整策略。 

      Serial Old 收集器:主要是Serial老年代版本,使用标记-整理算法

     Parallel old收集器:是Paralel Scavenge的老年代版本,基于标记-整理算法

   CMS收集器:cms 收集器是以最短回收停顿时间为目标的垃圾收集器。运作过程分为四个步骤:

       初始标记:

       并发标记

      重新标记: 

     并发清除:使用并发-清除算法,会存在空间碎片化导致空间不连续

    优点: 并发收集、低停顿、  缺点:由于在并发标记阶段,会占用一部分系统资源,导致总吞吐量降低,特别的处理器的核数比较低(低于4个)的时候。另外就是由于使用了标记-清除算法,会产生空间碎片导致空间不连续的问题。特别是在老年代时候,会出现明明有很大的内存空间,但是无法找到足够大的连续空间而触发一次full GC

    Garbage first(G1):g1收集器是面向局部收集以及基于Region的内存布局形式。R1把整个内存区域分为了多个Region,每个region 里面 有suvive/edon区域,以及专门存储大对象的Humongous区域,在做垃圾收集时候,他是通过回收不同的region区域来进行局部垃圾回收的,这种方式保证了G1收集器在有限时间获取尽可能高的收集效率。

       G1收集器也是分为四个步骤:

     初始标记:

     并发标记:

    最终标记:

   帅选标记: 

   g1整体上是采用标记-整理算法来实现的,但是局部的region上看又是基于标记-复制算法来的,相比cms来说,g1不会产生空间碎片且垃圾回收时间可控。但是相比cms也有一些缺点,比如G1为了垃圾收集产生的内存占用,以及程序运行时的额外负载,都要比cms要高。

   低延迟收集器:shenandoan ,基于Region布局,号称收集时间不超过10ms,但是目前尚未实现

                            ZGC:  基于标记-整理算法,开源给了OpenJDK,zgc出现在jdk11 上。

  垃圾回收的 可视化处理工具

  1.JDK自带的JCONSOLE以及使用dump 来分析,实际的工作上大部分是使用arthas 来分析。这个章节没有细看

 

 

 

    

        

         

标签:总结,Java,标记,对象,虚拟机,收集器,算法,JVM
From: https://www.cnblogs.com/thinkingandworkinghard/p/18429684

相关文章

  • 在虚拟机Linux上运行redis,同时使用Another RedisDesktop Manager图形化界面工具连接
    VMwareWorkstationPro虚拟机启动Centos7MobaXterm连接虚拟机输入个人密码Redis启动进入Redis文件目录cd/usr/local/src/redis-6.2.6Redis自启动systemctlenableredissystemctlstartredis查看Redis进程ps-ef|grepredis进入Redis操作redis-cli-h......
  • Mysql知识库【总结】
    MySQL是一种关系型数据库管理系统(RDBMS),其底层原理可以简单概括为以下几个方面:-存储引擎:MySQL支持多种存储引擎,如MyISAM、InnoDB、Memory等。每种存储引擎的实现方式不同,它们各自的特点和使用场景也不同。例如,MyISAM存储引擎适合于读多写少的场景,而InnoDB存储引擎则适合于......
  • 9.23考试总结
    T1简单签到题,考虑一个点从开头移到结尾会减去小于它的数加上大于它的数。所以\(O(nlogn)\)求逆序对,然后\(O(1)\)计算一个数移到最后的答案。#include<bits/stdc++.h>usingnamespacestd;constintN=1e6+10;#definelllonglongintn,a[N],sum[N],sh[N];llans,jg;......
  • JVM内存区域详解及DirectByteBuffer内存
    Java虚拟机(JVM)是Java程序运行的基础,它为Java程序提供了一个与平台无关的执行环境。JVM内存区域的划分对于理解Java程序的运行机制至关重要。本文将详细介绍JVM的内存区域,并探讨对外内存中的DirectByteBuffer。方法区(MethodArea)方法区是JVM中所有线程共享的内存区域。它主......
  • 2024/09/23 模拟赛总结
    rk3,\(0+100+30+5=135\)#A.依依寺唐氏分类讨论,赛事写了个记搜爆0了因为\(0\)不会改变取得数的和,所以\(a\)可以改为\(a\bmod2\)。接下来分类讨论假设先手取\(1\),那么后手取\(2\)直接输,则一定先取\(1\),接下来先手取\(1\)又输,只能取\(2\),然后就会循环后手\(1\)......
  • 总结
    集合考虑枚举子集和,统计有多少个子集的和为当前枚举的子集和,然后我们记个结论:\(x^y=x^{y\mod(p-1)}\),然后就过了P3488一眼二分图(网络流启动),但是考虑到图很大,所以我们考虑直接判断是否是二分图,考虑一个区间,如果总数比这个区间所能承载的人都要大,那么肯定会寄,所以用线段树维......
  • AI大模型大厂面经——LoRA面试题最全总结
    前言大家的显卡都比较吃紧,LoRA家族越来越壮大,基于LoRA出现了各种各样的改进,最近比较火的一个改进版是dora,听大家反馈口碑也不错。基于PEFT的话用409024G显存也可以进行大模型的微调,所以LoRA家族这块还是很有研究和实际落地的潜力。LoRA整个系列分为两个部分:1、LoRA总述2、LoRA家族......
  • NOIP2024集训 Day37 总结
    前言今天的题目也是比较快速的做完了。所以先来总结一下。今天是计数专题,组合数居多。以前做过的题目这里就稍稍略过了。MergeTriplets观察到对于能够得到的最终的排列\(p\),对于其中的一个数\(p_i\),不可能做到\(p_i>\max_{j=i+1}^{i+3}p_j\)。感觉是比较显然的,这里就不......
  • 【Java】JVM基本组成
    一、JDK、JRE、JVM        JDK:全称“JavaDevelopmentKit”Java开发工具包,提供javac编译器、jheap、jconsole等监控工具;        JRE:全称“JavaRuntimeEnvironment” Java运行环境,提供classLibrary核心类库+JVM;             ......
  • Arthas sysprop(查看和修改JVM的系统属性)
    文章目录二、命令列表2.1jvm相关命令2.1.4sysprop(查看和修改JVM的系统属性)举例1:sysprop查看所有系统属性举例2:syspropjava.version查看单个属性,支持通过tab补全二、命令列表2.1jvm相关命令2.1.4sysprop(查看和修改JVM的系统属性)参数说明:命令说明sysprop查看所有系统属性sys......