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

createh51个月前 (02-01)技术教程18
  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虚拟机(jvm)-简介(深入浅出:java虚拟机设计与实现)

一、Java运行时虚拟机内存区域划分1.元空间(Metaspace)元空间(Metaspace)从java8开始替换掉了原来的方法区(Method Area)。相比方法区(Method Area)在元...

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

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

JVM之Java编译到执行(1)——引(运行java编译器的命令)

Java语言特点一次编写,到处运行。也就是跨平台。 因为这个跨平台的实现原理,而导致Java的编译流程,与以往的C++之类语言有不同。各个操作系统的底层实现,资源的协调,和硬件操作各有各的不同。就意味...

“JVM” 上的 AOP:Java Agent 实战

作者:以奇在软件开发领域,面向切面编程(AOP)作为一种强大的技术手段,极大地促进了代码的模块化与可维护性,尤其在处理横切关注点方面表现出色。本文将深入探讨 Java 平台上的 AOP 实现,聚焦于...

美团架构师探秘Java生态系统,介绍JDK、JVM、JEP

OpenJDKOpenJDK原是Sun MicroSystems公司(下面简称Sun公司)为Java平台构建的Java开发环境,于2009年4月15日由Sun公司正式发布。后来Oracle公司在201...