java虚拟机基础(JVM)

java虚拟机基本组成

java的跨平台原理:

所谓java能实现跨平台,是因为在不同平台上运行不同的虚拟机所决定的,因为java文件的执行不直接在操作系统上执行,而是通过jvm来执行,jvm没有直接与硬件打交道,而是与操作系统交互用以执行java程序。这就是Java的能够“一次编译,到处运行”的原因。

Java运行流程

如上图所示,首先Java源文件经过前端编译器(javac或ECJ)将.java文件编译为Java字节码文件,然后JRE加载Java字节码文件,载入系统分配给JVM的内存区,然后执行引擎解释或编译类文件,再由即时编译器将字节码转化为机器码,然后再调用本地方法库进行执行。

 类加载器:将类的字节码文件(.class)中的二进制数据读入内存.

运行时数据区:在运行时数据区我们主要进行一些内存的分配、变量的引用,方法的调用。在堆上创建java.lang.Class对象,封装类在方法区内的数据结构。类加载的最终产品是位于堆中的类对象,类对象封装了类在方法区内的数据结构,并且向JAVA程序提供了访问方法区内数据结构的接口。

执行引擎: 由于底层操作系统并不能识别我们的java命令,而执行引擎会调用本地方法库来将java命令解释成底层操作系统上的机器指令来执行。

 Java运行时数据区域

程序计数器程序计数器(Program Counter Register),它是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的模型概念中,字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。程序计数器是在Java虚拟机规范中唯一一个没有规定任何OutOfMemoryError情况的区域,因为Java程序计数器它所需要存储的内容仅仅就是下一个需要待执行的命令的地址,其所需内存是创建时即可只晓的,不需要后期进行扩容等其他的操作。

Java虚拟机栈:Java虚拟机栈(Java Virtual Machine Stacks),Java虚拟机栈也是线程私有的,它的生命周期与线程相同。Java每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至方法执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

本地方法栈:本地方法栈(Native Method Stack)与虚拟机栈作用类似,它们之间的区别是虚拟机栈为虚拟机执行Java方法,而本地方法栈则为虚拟机执行Native方法服务。有些虚拟机会将本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈也会抛出StackOverflowErro和OutOfMemoryError异常。

 Native 方法:简单地讲,一个Native Method就是一个java调用非java代码的接口

Java堆:Java堆(Java Heap),对于大多数的应用来说,Java堆是虚拟机所管理的最大的一块内存。Java堆是被所有的线程所共享的,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都是在这里分配内存的(Java虚拟机规范中描述为所有的对象实例和数组都要在堆上分配内存)。Java堆是垃圾收集器管理的主要区域,因此很多时候也被称为GC堆。从内存回收的角度来看,由于现在收集器基本都是采用分代算法收集器,所以Java堆中还可以细分为:新生代和老年代青年代。

方法区:方法区(Method Area)与Java堆一样,是线程共享的,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。Java虚拟机规范堆方法区的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可拓展外,还可以选择不实现垃圾收集。相对而言,垃圾收集行为在这个区域是比较少出现的,这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说,这个区域的内存回收成绩比较令人难以满意,尤其时类型卸载,条件相当苛刻,但是这个区域的内存回收也是必要的。根据Java虚拟机规范规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

判断对象已死的算法

在堆中存放着各种各样的Java对象,垃圾收集器在对堆进行垃圾回收时,首先判断哪些对象还活着,哪些对象已死。、

引用计数器法:

给每一个对象添加一个引用计数器,每当有一个地方引用它时,计数器值加 1;每当有一个地方不再引用它时,计数器值减 1,这样只要计数器的值不为 0,就说明还有地方引用它,它就不是无用的对象。

可达性分析算法:

了解可达性分析算法之前先了解一个概念——GC Roots,垃圾收集的起点,可以作为 GC Roots 的有虚拟机栈中本地变量表中引用的对象、方法区中静态属性引用的对象、方法区中常量引用的对象、本地方法栈中 JNI(Native 方法)引用的对象。当一个对象到 GC Roots 没有任何引用链相连(GC Roots 到这个对象不可达)时,就说明此对象是不可用的,是死对象。

java中的四种引用

强引用(Strong Reference)

  • 写法:Object obj=new Object()
  • 引用强度:最强
  • 只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。

软引用(Soft Reference)

  • 写法:SoftReference<String> sr = new SoftReference<String>(new String("hello"));
  • 有用但并不是必需的对象。
  • 引用强度:第二
  • 当内存不足的时候JVM才会回收该对象。
  • 适用:实现缓存:比如网页缓存、图片缓存等。

弱引用(WeakReference)

  • 写法:WeakReference<String> wr = new WeakReference<String>(new String("hello"));;
  • 非必需对象。
  • 引用强度:第三
  • 当JVM进行垃圾回收无论内存是否充足,都会回收其对象。

虚引用(PhantomReference)

写法:ReferenceQueue<String> queue = new ReferenceQueue<String>(); PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue); ;
引用强度:最弱
任何时候都可能被垃圾回收器回收。
注意的是,虚引用必须和引用队列关联使用。

垃圾回收算法:

标记–清除算法:

执行步骤:

标记:遍历内存区域,对需要回收的对象打上标记。
清除:再次遍历内存,对已经标记过的内存进行回收。

在这里插入图片描述

在这里插入图片描述

缺点:
效率问题;遍历了两次内存空间(第一次标记,第二次清除)。
空间问题:容易产生大量内存碎片,当再需要一块比较大的内存时,无法找到一块满足要求的,因而不得不再次出发GC。

复制算法:

执行步骤:将内存划分为等大的两块,每次只使用其中的一块。当一块用完了,触发GC时,将该块中存活的对象复制到另一块区域,然后一次性清理掉这块没有用的内存。下次触发GC时将那块中存活的的又复制到这块,然后抹掉那块,循环往复。

在这里插入图片描述

在这里插入图片描述优点
相对于标记–清理算法解决了内存的碎片化问题。
效率更高(清理内存时,记住首尾地址,一次性抹掉)。 

缺点:

内存利用率不高,每次只能使用一半内存。

标记—整理算法:

执行步骤:
标记:对需要回收的进行标记
整理:让存活的对象,向内存的一端移动,然后直接清理掉没有用的内存。

在这里插入图片描述

在这里插入图片描述

分代收集算法:

分代收集算法将内存分为新生代和老年代,新生代又分为:较大的Eden区(占80%)和两块Survivor区(各占10%),在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。

注意:

1、将内存分为新生代和老年代,年轻代又分为Eden区和Survivor区,通常默认为8:1:1的比例,每次只保留10%的预留空间,90%的空间可用用做于新生代对象。

2、每次垃圾回收后,存活的对象年龄+1,当经历15次回收后依然存活的对象进入到老年代。

3、新生代中有内存担保机制,就是当新生代的空间不足的时候,会直接进入到老年代。

4、Minor GC指新生代GC,即发生在新生代(包括Eden区和Survivor区)的垃圾回收操作,当新生代无法为新生对象分配内存空间的时候,会触发Minor GC。因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快

5、Major GC清理Tenured区,用于回收老年代,出现Major GC通常会出现至少一次Minor GC。

6、Full GC是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。Full GC不等于Major GC,也不等于Minor GC+Major GC,发生Full GC需要看使用了什么垃圾收集器组合,才能解释是什么样的垃圾回收。
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值