入门JAVA必须了解的基础知识-JVM(java基础到入门)

createh51个月前 (02-01)技术教程19
  1. JAVA虚拟机(JVM)

JVM包含两个子系统和两个组件:类装载系统和执行引擎系统,运行时数据区和本地接口。如同一台真实的机器,有自己的指令集和执行引擎,可以在运行时操控内存区域,可以解读指令代码并与系统底层进行交互。

首先由编译器将JAVA代码转换成字节码,再由类加载器将字节码加载到内存中,保存在运行时数据区的元数据区内。字节码是JAVA虚拟机特定的一套指令集规范,操作系统无法识别运行,需经过JAVA虚拟机特定的执行引擎翻译成底层操作系统指令,再交由CPU执行。

  • 运行时数据区

java将所管理的内存分为5个区域:元数据,堆,虚拟机栈,本地方法栈和程序计数器。

  1. 元数据:主要用于存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。
  2. 堆:JAVA虚拟机内存管理中最大的一块,几乎分配保存所有的对象实例,被所有的线程序共享。
  3. 虚拟机栈:用于存储局部变量,操作数据栈,动态链接,方法出口等信息,由线程私有。
  4. 本地方法栈:与虚拟机栈作用一样,用于调用其他语言的第三方系统库接口。
  5. 程序计数器:当前线程所执行的字节码的行号指示器,通过改变计数器的值,来选取下一行指令,通过它主要实现跳转、循环、恢复线程等功能。一个CPU同一时刻只能运行一个线程,多线程通过抢占CPU运行,所以每个线程都需有一个标记来指示线程执行到哪里,以便恢复运行。若执行的是native方法,程序计数器中则为空。

堆和栈的区别:

  • 管理方式,堆需要GC,栈自动释放
  • 大小不同,堆比栈大
  • 碎片相关:栈产生的碎片远小于堆,因为GC不是实时的
  • 分配方式:栈支持静态分配内存和动态分配,堆只支持动态分配
  • 效率:栈的效率比堆的高


  • JAVA虚拟机最大的内存-堆

堆主要存储了JAVA的实例对象。java提供了5种创建对象方式:

  1. 通过new调用构造函数。
  2. 通过Class的newInstance方法调用构造函数。
  3. 通过Constructor类的newInstance方法调用构造函数。
  4. 通过类的clone方法
  5. 反序列化。

虚拟机接收到一条new创建对象的指令时,先检查元数据区常量池是否已加载了相应的类,如果没有则通过类加载器加载,再分配内存, 然后内存空间初始化操作, 最后执行初始化方法。

虚拟机有两种内存分配方式:

  1. 指针碰撞:如果Java堆的内存是规整,即所有用过的内存放在一边,而空闲的的放在另一边。分配内存时将位于中间的指针指示器向空闲的内存移动一段与对象大小相等的距离,这样便完成分配内存工作。

  2. 空闲列表:如果Java堆的内存不是规整的,则需要由虚拟机维护一个列表来记录那些内存是可用的,这样在分配的时候可以从列表中查询到足够大的内存分配给对象,并在分配后更新列表记录。


  • JVM堆及各种GC
  1. JAVA中的堆又可以分为两大部分:新生代和老年代

新生代:主要是用来存放新生的对象。一般占据堆的 1/3 空间。由于频繁创建对象,所以新生代会频繁触发 MinorGC 进行垃圾回收。

新生代又分为 Eden、S0、S1(SurvivorFrom、SurvivorTo)三个区:

  • Eden 区:Java 新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老年代)。
  • 当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行一次垃圾回收。
  • SurvivorFrom 区:上一次 GC 的幸存者,作为这一次 GC 的被扫描者。
  • SurvivorTo 区:保留了一次 MinorGC 过程中的幸存者。

Eden 和 S0,S1 区的比例为 8 : 1 : 1

老年代:

新生代的对象经过一次次的Minor GC后仍存活,年龄达到晋升老年代的年龄阈值(MaxTenuringThreshold, 默认:15)或同龄的对象超过新生代的一半,就会被晋升到老年代。老年代的对象都比较稳定,默认的新老年代内存比例为1:2。

在Major GC前一般都会先进行一次Minor GC,使得有新生代的对象晋升老年代,导致空间不够才触发的major GC。或者当有大对象创建但找不到足够的连续内存空间分配时也会触发一次Major GC。

  • JVM性能调优

java [options] MainClass [arguments]

  1. options: JVM启动参数。多个参数空格分隔
  2. arguments: 参数赋值。 -参数名=参数值 或 -参数名:参数值

内存参数:

  • -Xms: 初始化堆大小。
  • -Xmx: 最大堆大小。
  • -Xmn:新生代大小。
  • -Xss:每个线程java栈大小。
  • -XX:NewSize=n:年轻代大小。
  • -XX:NewRatio=n:年轻代与老年代的内存比例。默认1:2。
  • -XX:SurvivorRatio:年轻代中Eden区与两Survivor区的内存比例,默认8:1:1。
  • -XX:MaxTenuringThreshold=n:晋升老年代的最大年龄阈值,默认15。

垃圾回收器参数:

  • -XX:+UseSerialGC:使用串行收集器
  • -XX:+UseParallelGC:年轻代使用并行收集器
  • -XX:+UseG1GC:使用G1收集器
  • -XX:ParallelGCThreads=n:并行收集器收集时可使用的最大线程数
  • -XX:+UseCMSCompactAtFullCollection:老年代启用压缩,可能会影响性能但可以消除内存碎片。

相关文章

JVM(Java虚拟机)从0到1全部合集,强烈建议收藏

JVM(Java虚拟机)现在已经属于Java面试的重灾区,大厂面试现在基本属于必考内容,建议大家需要重点掌握。为了方便大家更好的掌握好JVM(Java虚拟机),也为了让知识更系统化,这里我单独把JVM...

Java 动态调试技术原理及实践(java的动态性指的是什么)

调试是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。最常用的断点调试技术会在断点位置停顿,导致应用停止响应。本文将介绍一种Java动态调试技术,希望能对大家有帮助。同时也欢迎读者朋友们一起交...

教你用Java开发一个简单的JVM(java开发实例教程)

一、前言几年前,接到一个开发任务:用Java开发能运行Java智能合约的虚拟机。在开发Java智能合约时,只能使用智能合约SDK提供的类和一些Java常用类(8种基本数据类型包装类;String、Bi...

JVM简介—1.Java内存区域(jvm内存分布包括哪些部分)

大纲1.运行时数据区的介绍2.运行时数据区各区域的作用3.各个版本内存区域的变化4.直接内存的使用和作用5.站在线程的角度看Java内存区域6.深入分析堆和栈的区别7.方法的出入栈和栈上分配、逃逸分析...

Java面试篇基础部分-JVM详细介绍(java面试必备 基础知识篇)

JVM的运行机制JVM(Java Virtual Machine)是用于运行Java字节码的虚拟计算机,其中包括一套字节码的指令集、程序寄存器、虚拟机栈、虚拟机堆、本地方法区、垃圾回收器。JVM运行在...

JAVA面试题每日一练:描述一下JVM加载class文件的原理机制?

Java是一门高度平台独立的编程语言,但在这个跨平台的特性背后,Java虚拟机(JVM)却承担了一个至关重要的任务:类加载。类加载不仅是Java程序执行的前提,它还是保证Java平台安全性和可扩展性的...