JVM学习笔记

JVM


1、什么是JVM?它是做什么的?

JVM是Java虚拟机的缩写。主要是将Java字节码解释或编译为机器码,可在不同操作系统和硬件平台运行Java程序。一次编写,到处运行。

​ JVM有以下主要任务:

  • 类加载:将子字节码加载到内存中,将其转化为可执行的类。

  • 字节码执行:编译字节码。

  • 内存管理:JVM管理程序的内存分配和释放。

  • 垃圾回收:检测和回收不再使用的对象,释放内存空间。

  • 安全管理:提供安全机制,确保Java在受控环境运行,防止恶意代码执行。

  • 线程 管理:允许多线程执行。提供线程同步和协作的机制。

  • 异常处理:可捕获和处理Java中异常。

2、JVM的组成部分有哪些?

​ ①类加载器:将字节码文件加载到JVM中,并将其转换为可执行的类。

​ ②运行时数据区:jvm将内存划分为不同数据区域,存储程序运行时的数据。主要包含方法区:存储类结构信息,静态变量,常量池。

		堆:存储对象实例和数组。
		java栈:每个线程运行时都会创建一个栈,存储局部变量,方法参数等。
		本地方法栈:执行本地方法所用。
		程序计数器:指示当前线程正在执行的指令地址。

​ ③执行引擎:解释和执行字节码。

​ ④垃圾回收器:自动管理内存,回收不再使用的对象。

​ ⑤本地方法接口:允许Java程序调用本地方法库中的方法。

​ ⑥可拓展性:JVM提供了一系列工具和接口,用于诊断和监控应用程序的性能、调试代码和进行性能优化。

3、什么是字节码?为什么Java使用字节码?

		字节码是Java编译器将Jaava代码编生成的中间代码。

​ 使用字节码主要原因:

  • 平台无关性
  • 安全性:字节码执行之前JVM会进行安全检查。
  • 性能优化:字节码被即时编译器动态编译为本地机器码,提高效率。
  • 可以执行:不依赖特定平台。
  • 开发效率:编译更快。

4、什么是即时编译器(Just-In-Time Compiler)?它与解释器有什么区别?

			 即时编译器是将字节码动态编译成本地机器码,提高程序执行效率。 

和解释器的区别如下:

​ ①执行方式:解释器是逐条解释执行字节码,即时编译器是在运行时将频繁执行的代码编译为本地机器码,直接执行编译后的机器码。

​ ②执行效率:解释器每次执行都要解释字节码执行,慢;

​ 即时编译器将热点代码编译后直接执行机器码,快。

​ ③优化能力:解释器每次执行都会解释,没有优化机会。

​ 即时编译器可以动态对热点代码优化,提高效率。

​ ④编译延迟:解释器可以立即执行,不需要等待编译。

​ 即时编译器在运行时编译热点代码,刚启动存在延迟。

​ ⑤内存占用:解释器占用内存较少。

​ 即时编译器在编译过程中会生成本地机器码,需要更多空间。

5、JVM内存分为哪些区域?请描述它们的作用和特点。

  • 程序计数器:指示当前线程正在执行的字节码指令的地址。
  • Java虚拟机栈:存储线程的方法和局部变量等信息。
  • 本地方法栈:存储本地方法,局部变量等信息。
  • 堆:存储对象实例和数组。分为新生代和老年代。新生代又分为伊甸区和Survivor区。
  • 方法区:存储一家在的类的信息、常量、变量等。
  • 运行时常量池:存储编译器生成的各种字面量和符号引用。

6、堆的详解,新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

​ 用于存储对象实例和数组。划分为新生代和老年代。

新生代:

  • Eden区:对象被创建时首先分配在Eden区。Eden区满时,出发Young GC进行垃圾回收。幸存对象会被移动到Survivor区。
  • Survivor区:分为From区和To区。Minor GC发生时,幸村对象从Eden区和From区复制到To区,复制过程中对象年龄逐渐增加,多次幸存后,会一共到老年区。

老年代:
分为
CMS收集器:采用并发标记和并发清除方式进行垃圾回收。
G1收集器:采用分代收集和并发标记清除方式,将堆划分为多个区域,处理。
Serial Old收集器:采用单线程进行垃圾回收。

​ 存储多次经过Minor GC后仍然存活的对象。新生代经历多次幸存后,会晋升到老年代。老年代的垃圾回收频率更低,对象存活 更稳定。老年代满时,会触发Full GC进行垃圾回收。

区别

新生代
    主要负责回收新创建的对象,一般采用复制算法。分区,
	将内存分为Eden区、Survivor区From和Survivor区To。通过将存活的对象复制到Survivor区,
	然后清空Eden区和From区的方式来回收垃圾。
老年代
    主要回收存活时间长的对象,一般采用标记清除算法,
	老生代垃圾回收器通常需要在停顿的情况下进行垃圾回收,可能会导致较长的停顿时间

7、Java对象在内存中是如何分配的?请解释堆和栈的区别。

​ 对象实例存储在堆中,堆是动态分配的内存区域。

​ Java中的方法和局部变量存储在栈(stack)中。栈是一种具有后进先出(LIFO)特性的数据结构。

​ 堆的分配和释放相对较慢,

​ 栈的分配和释放速度非常快,但是栈的大小是有限的。当方法调用嵌套层级过深或者局部变量过多时,栈可能会溢出,导致栈溢出错误。

		1、存储内容:堆存储对象实例和数组,栈存储方法调用和局部变量。
		2、线程共享:堆被所有线程共享。每个线程都有自己的栈。
		3、内存管理:堆是动态分配,由垃圾回收器分配和销毁。栈是自动的,随着方法的调用和返回自动分配释放。
		4、内存大小:堆是可以通过jvm配置,栈 固定。
		5、异常:堆空间不足导致OutOfMemmoryErrror,栈内存不足导致StackOverFlowError。

8、什么是垃圾回收(Garbage Collection)?为什么需要进行垃圾回收?

​ 垃圾回收用于检测和回收程序中不再使用的资源,

​ 需要进行垃圾回收的原因:

  • 防止内存泄漏:对象或者数据不再使用,如果不回收,会一直占用内存空间。
  • 动态内存管理:动态创建对象,减少手动释放。
  • 提高性能:根据程序的运行情况智能地管理内存,减少内存碎片化的问题。

9、垃圾回收器有哪些类型?请描述它们的工作原理和适用场景。

  • ​ 标记-清除:分为标记阶段和清除阶段,
  • ​ 复制:分为活动区域,和回收区域,活动区满了的情况下将存活的对象复制到回收区,清除活动区所有对象。
  • ​ 标记-压缩:它首先通过标记阶段标记可达对象,然后将存活对象紧凑地移动到内存的一端,清除边界之外的内存空间。
  • ​ 分代:新生代、老年代。

10、如何判断对象是否可以被垃圾回收?

      1、可达性分析算法:垃圾回收器自动判断。Java中的垃圾回收器使用可达性分析算法判断对象是否可以被回收。
      		如果对象不再被任何活动的引用链所引用,那就是不可达,可以被回收。
      2、引用计数法:每个对象都有一个引用计数器,当有引用指向该对象时,计数器加1,当引用失效时,计数器减1。
      		当计数器为0时,表示该对象不再被引用,可以被回收。
      3、引用队列: 将某些对象的引用放入队列中。当这些对象变为不可达时,它们会被添加到引用队列中,
      		开发人员可以在合适的时机、处理这些对象。

11、什么是类加载器(ClassLoader)?它的作用是什么?请解释双亲委派模型。

		类加载器负责将Java类的字节码加载到内存中,将其转化为可执行的java对象。

​ 双亲委派模型是类加载器的一种,当一个类加载器需要加载某个类时,它首先将任务委托给父类加载器。如果父类加载器无法加载该类,子类加载器才会尝试加载。

​ 双亲委派模型优点:

		1、避免类重复加载:先检查父类有没有祖先加载过,避免重复加载同一个类。
		2、安全性
		3、类的隔离性:不同类加载器加载位于不同命名空间的类,相同类名的类可以被不同的类加载器加载。

12、类加载的过程是怎样的?请解释加载、验证、准备、解析和初始化这五个阶段的含义。

  1. 加载:将类的字节码文件加载到jvm。

  2. 验证:确保加载的字节码文件是否符合规范。

  3. 准备:为类的静态便令在内存中分配空间,设置初始值。

  4. 解析: 将符号引用转为直接引用。

  5. 初始化: 按顺序执行静态变量的初始化和静态代码块中的代码。

13、什么是永久代(Permanent Generation)和元数据区(Metaspace)?它们的作用是什么?

​ 永久代:用于存储类的相关信息,如类的结构信息,运行时常量池,静态便令,即时编译器编译后的代码等。

​ 永久代的大小是有限的,

​ 元数据区主要是存储类的元数据信息,可以动态加载类,大小可以通过jvm参数进行配置,可以自动拓展。

14、Java中的String为什么被设计为不可变类?有什么好处?

​ 1、字符串池的优化:String是不可变的,所以相同内容的字符串在内存中只需要存储一份。创建新对象时,jvm首先检查池中是否存在相同内容的,如果存在,直接返回引用。可节省空间,提高性能。

​ 2、线程安全:值不可变。多个线程可以共享同一个String对象。

​ 3、缓存哈希值:String类在创建时会计算并缓存它的哈希值。之后再次需要哈希值时可以直接使用缓存的值,提高了性能。

​ 4、安全性。

​ 5、方法和参数传递:String不可变,更安全。

15、如何进行JVM性能调优?请列举一些常见的优化技巧和工具。

​ 1、内存管理:通过-Xmx和-Xms调整堆的最大和初始化大小。

​ 2、线程管理:减少线程数量,避免创建过多线程。选择合适的线程池。

​ 3、代码优化:减少对象创建。减少堆共享资源的锁竞争。

​ 4、JVM参数调优。调整堆和栈大小:通过-Xmx、-Xms和-Xss参数调整堆和栈的大小,以满足应用程序的需求。

16、详细介绍一下 CMS 垃圾回收器?

		CMS采用了并发标记-清除算法。

回收流程:

  1. 初始标记:标记所有对象。这个阶段是暂停应用程序的阶段。
  2. 并发标记阶段:应用程序继续运行,垃圾收集器与应用程序并发执行。垃圾收集器通过遍历堆中的对象,
    标记出所有可达对象。
  3. 重新标记阶段:并发标记结束,在此暂停应用程序重新标记,标记在并发阶段发生变化的对象。
  4. 并发清除阶段:重新标记之后,垃圾收集器并发运行,进行清除操作。释放未被引用的对象占用的内存空间。

17、简述分代垃圾回收器是怎么工作的?

    分代垃圾回收器通过根据对象的生命周期将堆内存划分为不同的代,
    并根据每个代的特性采取不同的垃圾回收策略,以提高垃圾回收的效率和性能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值