《深入理解JAVA虚拟机》学习笔记

1.java内存结构,以及每个结构的作用?
  • 线程共享区

      堆内存:所有的对象实例都要在堆上分配
      
      方法区:是各个线程共享的内存区域,
      
      它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
    
  • 非线程共享区

      Java虚拟机栈:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息
      
      本地方法栈:虚拟机调用本地方法的区域
      
      程序计数器:当前线程所执行的字节码的行号指示器
    

java1.8:

以后在JDK1.8中元空间区取代了永久代,永久代原本主要存放Class和Meta的信息。

而元空间的本质和永久代类似,都是对JVM规范中方法区的实现。

不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。

因此,默认情况下,元空间的大小仅受本地内存限制。

2.什么是java垃圾回收机制?

java内存是有限的,需要不定时去回收不可达的对象,如果不进行垃圾回收,

内存迟早会被消耗空。

3.垃圾回收的过程,以堆内存结构去分析?

新生代(1/3) 老年代(2/3)

新生代分为:Eden伊甸园、from(s0)、to(s1)

​ (8/10) (1/10) (1/10)

1).判断哪些对象是垃圾

2).垃圾回收算法

4.如何判断对象是否存活?
  • 引用计数法:

      如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到环的存在。
      
      首先需要声明,至少主流的Java虚拟机里面都没有选用引用计数算法来管理内存。 
      
      什么是引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,
      
      计数器值加1;当引用失效时,计数器值减1.任何时刻计数器值为0的对象就是不可能再被使用的。
      
      那为什么主流的Java虚拟机里面都没有选用这种算法呢?
      
      其中最主要的原因是它很难解决对象之间相互循环引用的问题
    
  • 根搜索算法:

      根搜索算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,
      
      从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),
      
      当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
      
      那么问题又来了,如何选取GCRoots对象呢?在Java语言中,可以作为GCRoots的对象包括下面几种:
      
      (1). 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。
      
      (2). 方法区中的类静态属性引用的对象。
      
      (3). 方法区中常量引用的对象。
      
      (4). 本地方法栈中JNI(Native方法)引用的对象。
      
      下面给出一个GCRoots的例子,如下图,为GCRoots的引用链。
    

img

img

5.有哪些垃圾回收算法?
  • (1).标记-清除:

应用场景:

该算法一般应用于老年代,因为老年代的对象生命周期比较长。

该算法有两个阶段。

  1. 标记阶段:找到所有可访问的对象,做个标记

  2. 清除阶段:遍历堆,把未被标记的对象回收

优点:

是可以解决循环引用的问题

必要时才回收(内存不足时)

缺点:

标记和清除的效率不高,尤其是要扫描,尤其是要扫描的对象比较多的时候

会造成内存碎片(会导致明明有内存空间,但是由于不连续,申请稍微大一些的对象无法做到)

  • (2).复制算法:

复制算法一般使用在新生代中,因为新生代中的对象一般都是朝生夕死,存活的对象并不多,

这样使用coping算法进行拷贝时效率高。

如果jvm使用了cpying算法,一开始就会将可用内存分为两块,from(s0)域和to(s1)域,

每次只是使用from域,to域则空闲着。当from域内存不够了,开始执行GC操作,这个时候,

会把from域存活的对象拷贝到to域,然后直接把from域进行清理

步骤:1.当Eden区满的时候会触发第一个young gc,把还活着的对象拷贝到From;

当Eden区再次触发young gc的时候,会扫描Eden区和From区域,对两个区域进行垃圾回收,

经过这次回收后还存活的对象,直接复制到To区域,并将Eden和From区域清空。

2.当后续Eden又发生young gc的时候,会对Eden和To区域进行垃圾回收,存活的对象复制到From区域,

并将Eden和To区域清空。

3.可见部分对象会在From和To区域中复制来复制去,如此交换15次(由jvm参数MaxTenuringThreshold决定,

这个参数默认值是15),最终如果还是存活,就存入到老年代。

注意!!!:万一存活对象比较多,那么To域的内存可能不够存放,这个时候会借助老年代的空间。

优点:在存活对象不多的情况下,性能高,能解决内存碎片和标记清除算法中导致更新的问题。

缺点:会造成一部分内存浪费,因为有一部分内存是空的,不过可以根据实际情况,将内存块大小

比例适当调整;如果存活对象的数量比较大,coping的性能会变得很差。

  • (3).标记-压缩算法:

标记清除算法和标记压缩算法非常相同,

但是标记压缩算法在标记清除算法之上解决内存碎片化

优点:解决内存碎片问题

缺点:压缩阶段,由于移动了可用对象,需要去更新引用。

  • (4).分代算法:

当前商业虚拟机的GC都是采用的’分代收集算法’,这并不是什么新的思想,只是根据对象的

存活周期的不同将内存划分为几块儿。

少量对象存活,适合复制算法,一般用在新生代

大量对象存活,适用于标记整理算法/标记清除算法

6.Minor GC和MajorGC、Full GC区别

年轻代满时会触发Minor GC,这里的年轻代满是指Eden区满。

老年代满时会触发MajorGC,只有CMS收集器会有单独收集老年代的行为,其他收集器均无此行为。

FullGC是针对新生代,老年代和方法区(元空间)的垃圾收集。FullGC产生的条件:

(1)调用System.gc时,系统建议执行Full GC,但是不一定会执行 。

(2)老年代空间不足。

(3)方法区空间不足,类卸载(类卸载三个条件)。

(4)通过 Minor GC 后进入老年代的空间大于老年代的可用内存

(5)内存空间担保。

7.JVM会在永久代中发生垃圾回收吗?

垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)。

如果你仔细查看垃圾回收器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的

永久代大小对避免Full GC是非常重要的原因。(注意:java8中已经移除了永久代,新加了一个叫元数据区的

native内存区)

8.OutOfMemoryError异常如何解决?
  • java堆溢出

错误原因:java.lang.OutOfMemoryError: Java heap space 堆内存溢出

解决办法:设置堆内存大小 // -Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

  • 虚拟机栈溢出

错误原因:java.lang.StackOverflowError 栈内存溢出

栈溢出 产生于递归调用,循环遍历是不会的,但是循环方法里面产生递归调用,也会发生栈溢出。

解决办法:设置线程的最大深度调用

-Xss5m 设置最大调用深度

9.内存溢出和内存泄露的区别?
  • 内存溢出(Out Of Memory) :就是申请内存时,JVM没有足够的内存空间。通俗说法就是去蹲坑发现坑位满了。
  • 内存泄露 (Memory Leak):就是申请了内存,但是没有释放,导致内存空间浪费。通俗说法就是有人占着茅坑不拉屎。
10.有哪些常用的垃圾回收器?

serial串行收集器、ParNew收集器、parallel收集器、cms收集器、g1收集器

11.jvm调优思路?

初始堆值和最大堆内存内存越大,吞吐量就越高。

最好使用并行收集器,因为并行收集器速度比串行吞吐量高,速度快。

设置堆内存新生代的比例和老年代的比例最好为1:2或者1:3。

减少GC对老年代的回收。

12.类加载的过程?

一个类从加载到内存开始,一直到被卸载结束,它的整个生命周期包括加载,连接

加载—>验证—>准备—>解析—>初始化—>使用—>卸载

​ <------连接Linking---->

img

加载(Load):类加载过程的一个阶段,ClassLoader通过一个类的完全限定名查找此类字节码文件,

并利用字节码文件创建一个class对象

验证(Verify):目的在于确保class文件的字节流中包含符合当前虚拟机要求,不会危害虚拟机自身的安全,主要包括四种验证:文件格式的验证,元数据的验证,字节码验证,符号引用验证。

验证一个Class的二进制内容是否合法

准备(Prepare):

在准备阶段,虚拟机会在方法区中为Class分配内存,并设置static成员变量的初始值为默认值.

注意这里仅仅会为static变量分配内存(static变量在方法区中),并且初始化static变量的值为其所属类型的默认值.如:int类型初始化为0,引用类型初始化为null.即使声明了这样一个static变量:

​ public static int a=123;

在准备阶段后,a在内存中的值仍然是0,赋值123这个操作会在中初始化阶段执行,因此在初始化阶段产生了对应的Class对象之后a的值才是123.

解析(Resolve):解析阶段,虚拟机会将常量池中的符号引用替换为直接引用,解析主要针对的是类,接口,方法,成员变量等符号引用. 在转换成直接引用后,会触发校验阶段的符号引用验证,验证转换之后的直接引用是否能找到对应的类,方法,成员变量等. 这里也可见类加载的各个阶段在实际过程中,可能是交错执行.

初始化(Initialize):初始化阶段是类加载过程的最后一步,这个阶段才开始的真正的执行用户定义的java程序.在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则需要为类变量(非final修饰的变量)和其他变量赋值,其实就是执行类的()方法.

初始化阶段即开始在内存中构造一个Class对象来表示该类,即执行类构造器()的过程。

13.双亲委派模式?

img

img

上图是上面所介绍的这几种类加载器的层次关系,称为类加载器的双亲委派模型.

该模型要求除了顶层的启动类加载器外,其他的类加载器都要有自己的父类加载器.

一言概之,双亲委派模型,其实就是一种类加载的层次关系.

工作过程:

如果一个类加载器收到了类加载的请求,它首先不会自己区尝试加载这个类,而是把这个委派给

加载器去完成,每一个层次的类加载器都是如此.

因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需要的类)时,子类加载器才会尝试去加载.

采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次

14.双亲委派模式优势

采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。其次是考虑到安全因素,java核心api中定义类型不会被随意替换,假设通过网络传递一个名为java.lang.Integer的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的java.lang.Integer,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。可能你会想,如果我们在classpath路径下自定义一个名为java.lang.SingleInterge类(该类是胡编的)呢?该类并不存在java.lang中,经过双亲委托模式,传递到启动类加载器中,由于父类加载器路径下并没有该类,所以不会加载,将反向委托给子类加载器加载,最终会通过系统类加载器加载该类。但是这样做是不允许,因为java.lang是核心API包,需要访问权限,强制加载将会报出如下异常

15.线上如何去排查分析内存溢出的问题?

设置虚拟机参数生成堆内存dump日志文件—>使用分析工具去分析具体线程所占用的内存—>分析具体的数据结构代码—>分析代码—>修改紧急上线

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sentinel使用

前言&#xff1a; 所有的准备工作都做好了&#xff0c;就可以进入到Sentinel的具体使用上了&#xff0c;这里还需要一个测试工具叫做jmeter&#xff0c;是一个很好的测试工具&#xff0c;专门针对并发的&#xff0c;准备好以后&#xff0c;就可以直接开干了。 一、Sentinel作用…

2下载Spring,第一个Spring程序+Log4j

https://www.yuque.com/dujubin/ltckqu/kipzgd#&#xff0c;注意的是&#xff0c;现在&#xff08;202401&#xff09;SpringFramework从release搬到了snapshot下&#xff0c;在这下面找到6.0.2下载. 下载后解压到文件夹&#xff0c;整个框架包含非常多jar包。 然后就可以在p…

UMLChina书籍大全(2024)软件方法人月神话人件企业应用架构模式UML参考手册彩色UML建模领域驱动设计对象设计……

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 以下列出有UMLChina标记的书。 首先是写了十几年还没有写完的软件方法 其他的是译作&#xff1a; 人月神话 2002年&#xff0c;UMLChina和清华大学出版社合作&#xff0c;翻译了《人…

linux性能优化

文章目录 性能优化图CPU进程和cpu原理性能指标 性能优化图 CPU 进程和cpu原理 进程与线程&#xff1a; 进程是程序的执行实例&#xff0c;有自己的地址空间和系统资源。线程是进程内的执行单元&#xff0c;共享进程的资源。在多核系统中&#xff0c;使用多线程可以更好地利用多…

倒排索引

正向索引&#xff1a;id&#xff08;序号&#xff09;--》 内容&#xff08;文档或记录&#xff09;--》关键词 &#xff0c;这个过程。 倒排索引&#xff1a;关键词 --》id&#xff08;序号&#xff09;--》内容&#xff0c;这个过程。 在有些图书的最后也有倒排索引的例子 …

Elasticsearch 中映射参数doc_values 和 fielddata分析比较

一、doc_values 默认情况下&#xff0c;大部分字段是索引的&#xff0c;这样让这些字段可被搜索。倒排索引&#xff08;inverted index&#xff09;允许查询请求在词项列表中查找搜索项&#xff08;search term&#xff09;&#xff0c;并立即获得包含该词项的文档列表。 倒排…

适口性好的猫粮:性价比高的主食冻干测评推荐

冻干猫粮因其高营养和适口性&#xff0c;受到了众多铲屎官们的喜爱和追捧。冻干猫粮的喂养方式非常简单&#xff0c;可以直接喂食&#xff0c;也可以将冻干复水后喂食&#xff0c;根据猫咪的不同喜好可以选择不同的喂养方式。然而&#xff0c;有些铲屎官在选择冻干猫粮时会担心…

反距离加权水平内插,附matlab代码(ERA5和GNSS站点不并址的处理方法之水平补偿)

1.内插方法 我在学习过程&#xff0c;内插方法为反距离加权水平内插&#xff0c;分享我的方法和公式&#xff0c;以及matlab代码。 2.使用该内插法的原因 GNSS与ERA5格网位置不并址&#xff0c;需要进行水平方向和垂直方向的补偿的补偿获得。水平方向不并址如第3节图所示&am…

羊大师讲解,羊奶为什么更适合高血压人群?

羊大师讲解&#xff0c;羊奶为什么更适合高血压人群&#xff1f; 高血压是一种常见的健康问题&#xff0c;它会引起诸多并发症并增加心脑血管疾病的风险。与此同时&#xff0c;人们越来越关注饮食对健康的影响。作为一种营养丰富且适合高血压人群的饮品&#xff0c;羊奶备受关…

如何使用 Python+selenium 进行 web 自动化测试?

Selenium是一个自动化测试工具&#xff0c;它可以模拟用户在浏览器中的操作&#xff0c;比如点击、输入、选择等等。它支持多种浏览器&#xff0c;包括Chrome、Firefox、Safari等等&#xff0c;并且可以在多个平台上运行。 安装和配置Selenium 在使用Selenium之前&#xff0c;…

error:0308010C:digital envelope routines::unsupported 前端项目错误

直接启动命令中增加&#xff1a; SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-service serve

WebGIS开发的常见框架及优缺点

WebGIS开发引擎的发展历程&#xff1a; 内容来自公众号&#xff1a;Spatial Data 地图API分类 WebGIS系统通常都围绕地图进行内容表达&#xff0c;但并不是有地图就一定是WebGIS&#xff0c;所以下面要讨论下基于Web的地图API分类及应用场景。Web上的Map API主要分类&#xff…

不要盲目自学网络安全!学习顺序特别重要!

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…

【QT 5 +Linux下+录屏软件使用+总结说明+使用录屏软件+简单软件使用+SimpleScreenRecorder+操作说明】

【【QT 5 Linux下录屏使用录屏软件简单软件使用SimpleScreenRecorder操作说明】】 1、前言2、实验环境3、录屏软件综述SimpleScreenRecorder&#xff1a;Kazam&#xff1a;OBS Studio (Open Broadcaster Software)&#xff1a;VokoscreenNG&#xff1a;RecordMyDesktop&#xf…

Jmeter如何添加插件

一、前言 ​ 在我们的工作中&#xff0c;我们可以利用一些插件来帮助我们更好的进行性能测试。今天我们来介绍下Jmeter怎么添加插件&#xff1f; 二、插件管理器 ​ 首先我们需要下载插件管理器jar包 下载地址&#xff1a;Install :: JMeter-Plugins.org 然后我们将下载下来…

【unity小技巧】Unity音乐和音效管理器

最终效果 前言 在游戏开发中&#xff0c;音乐和音效的管理是一个重要的环节。好的音乐和合适的音效可以为游戏增添氛围并提升玩家的体验。为了更好地管理音乐和音效&#xff0c;我们可以使用一个专门的音乐和音效管理器。 在本文中&#xff0c;我将向大家介绍如何在Unity中创…

Android 文字垂直排列,文字向右旋转90度

public class VerticalTextView extends View {private final int ROTATION_ANGLE 90; // 旋转角度&#xff0c;用于将文本垂直排列private String text; // 要显示的文本private TextPaint textPaint; // 用于绘制文本的画笔private Rect textBounds;// 文本边界float x, y;/…

Spring Boot 3 集成 Thymeleaf

在现代的Web开发中&#xff0c;构建灵活、动态的用户界面是至关重要的。Spring Boot和Thymeleaf的结合为开发者提供了一种简单而强大的方式来创建动态的Web应用。本文将介绍如何在Spring Boot项目中集成Thymeleaf&#xff0c;并展示一些基本的使用方法。 什么是Thymeleaf&#…

spug发布问题汇总记录

问题导览 1. [vite]: Rollup failed to resolve import "element-plus" from "src/main.js". 项目框架简介 vue3viteelement-plus 解决方案 - 1. 配置淘宝镜像源&#xff1a;npm config set registry https://registry.npm.taobao.org/ - 2. npm inst…

Spring框架-入门(IOC,DI)

文章目录 Spring框架简介创建Spring项目理解IOC和DI&#xff1a;IOC控制反转示例pom.xmlPerson.javaapplicationContext.xmlPersonTest.java DI依赖注入传统的方式GreetingService.javaGreetingServiceImpl.javaGreetingTest.java 使用DI依赖注入GreetingService.javaGreetingS…