JAVA 简单理解JVM概念分析与GC机制

来源:互联网 发布:肝脏再造术的真假知乎 编辑:程序博客网 时间:2024/06/06 10:43

Java虚拟机(JVM)

概念:JVM是Java Virtual Machine的缩写,它是可以通过类加载器把Class文件加载到自己运行时内存中去执行的虚拟机。虚拟机是运行在操作系统中的,而进程又是操作系统的执行单位,所以当java虚拟机运行的时候,它就是操作系统中的进程实例,当它没运行时,可以把它叫做程序。

一、四个组成部分

1、类加载器(ClassLoader):在JVM启动时或者在类运行时将需要的class加载到JVM中。

2、执行引擎:负责执行class文件中包含的字节码指令。

3、内存区(也叫运行时数据区):是在JVM运行的时候操作所分配的内存区。运行时内存区主要可以划分为5个区域。
  1. 方法区(Method Area):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分, 但它却有个别名non-heap(非堆),所以大家不要搞混淆了。方法区还包含一个运行时常量池。
  2. java堆(Heap):存储java实例或者对象的地方。这块是GC的主要区域。从存储的内容我们可以很容易知道,方法区和堆是被所有java线程共享的。
  3. java栈(Stack):java栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的java栈。在这个java栈中又会包含多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表、操作栈、方法返回值等。每一个方法从调用直至执行完成的过程,就对应一个栈帧在java栈中入栈到出栈的过程。所以java栈是现成私有的。
  4. 程序计数器(PC Register):用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器也是线程私有的。
  5. 本地方法栈(Native Method Stack):和java栈的作用差不多,只不过是为JVM使用到的native方法服务的。

4、本地方法接口:主要是调用C或C++实现的本地方法及返回结果。

二、虚拟机GC机制

我们知道,Java虚拟机会自动管理内存,即自动释放没用的对象,不需要程序员编写代码来释放分配的内存。这部分工作由垃圾收集器子系统负责。垃圾收集器必须完成的两件事:检测垃圾、回收垃圾。

1、怎么检测出垃圾?一般有以下几种方法:

  • 引用计数法:给一个对象添加引用计数器,每当有个地方引用它,计数器就加1;引用失效就减1。好了,问题来了,如果我有两个对象A和B,互相引用,除此之外,没有其他任何对象引用它们,实际上这两个对象已经无法访问,即是我们说的垃圾对象。但是互相引用,计数不为0,导致无法回收,所以还有另一种方法:
  • 可达性分析算法:以根集对象为起始点进行搜索,如果有对象不可达的话,即是垃圾对象。这里的根集一般包括java栈中引用的对象、方法区常良池中引用的对象、本地方法中引用的对象等。


2、JVM在做垃圾回收的时候,会检查堆中的所有对象是否会被这些根集对象引用,不被引用的对象就会被垃圾收集器回收。一般回收算法也有如下几种:

  • 标记-清除(Mark-sweep)
  • 复制(Copying
  • 标记-整理(Mark-Compact)
  • 分代收集算法
详细参考: Java 垃圾回收的GC机制原理简单分析

三、总结

  1. 虚拟机在操作系统的角度看来,它只是一个普通进程。
  2. 虚拟机的进程能够加载class文件。如果把JVM比作一个吃货,那么class文件就是食物。加载class文件就好比我们的嘴巴把食物吃到肚子里。
  3. 虚拟机中的执行引擎用来执行class文件中的字节码指令。就好比我们的肠胃,对吃进去的食物进行消化。
  4. 虚拟机在执行过程中,要分配内存创建对象。当这些对象过时无用了就必须要自动清理。清理对象回收内存的任务由垃圾收集器负责。就好比人吃进去的食物,在消化之后,必须把废物排出体外,腾出空间可以给下次吃饭并消化食物。

原创粉丝点击