您的位置:首页 > 其它

浅谈JVM

2017-01-20 13:41 148 查看
简介

JVM是Java虚拟机的缩写,是一个虚拟出来的计算机。

Java语言最重要的特点就是与平台无关性,而使用Java虚拟机是实现这一特点的关键。一般高级语言如果要在不同的平台上运行,就要编译成不同的目标代码,而Java语言不需要重新编译。它使用Java虚拟机屏蔽了与具体平台相关的信息。Java虚拟机在执行字节码时,将字节码解释成具体平台的机器指令执行。这就是Java能够“一次编译,到处运行”的原因。
JVM的生命周期

a. 启动:启动一个Java程序时,一个JVM实例就产生了。任何一个拥有public static void main(String args[])函数的class都可以作为JVM实例运行的起点。

b. 运行:main()方法作为程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程。main()方法属于非守护线程,守护线程是由JVM自己使用的。Java程序也可以标明自己创建的线程是守护线程。

c. 消亡:当程序中所有的非守护线程都终止时,JVM才退出。
JVM的体系结构

a.类加载器(ClassLoader):用来加载.class文件

虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,解析和初始化,最终形成可以被虚拟机直接使用的Java类型。

实现通过权限名获取该类的二进制字节流的代码叫做类加载器。

主要有四种类加载 :

        (1)启动类加载(bootstrap classloader)用于加载Java核心类库,无法被Java直接引用。

        (2)扩展类加载(extensions classloader)用于加载Java的扩展类。

        (3)系统类加载(system classloader)用于加载Java应用的类。

        (4)用户自定义类加载通过继承java.lang.classLoader类来实现。

b.运行时数据区

        (1)方法区:即永久代,在该区很少发生垃圾回收,但并不代表不发生垃圾回收。主要用来存储已被虚拟机加载的类信息,常量,静态变量和即时编译器编译后的代码,是线程共享的。

        (2)虚拟机栈:即栈内存,他为Java方法服务,每个方法在执行的时候都会创建一个栈,用以存储局部变量表,操作数栈等信息,是线程隔离的。

        (3)本地方法栈:和虚拟机栈类似,只不过本地方法栈为native方法服务。

        (4)堆:Java堆是所有线程共享的一块内存,在虚拟机启动时创建,几乎所有的对象实例都在这里创建,因此该区域经常发生垃圾回收操作。

        (5)程序计数器:是一个比较小的内存区域,用来指示当前线程执行的字节码执行到了第几行,是线程隔离的。
java垃圾回收机制

在Java中,程序员不需要显示的释放一个对象的内存,而是由虚拟机自行执行。在JVM中,有一个垃圾回收线程,他是低优先级的。在正常情况下是不能执行的。只有虚拟机空闲或者当前堆内存不足的时候,才会触发执行,扫描那么没有被任何引用的对象,并将它们添加到要回收的集合中进行回收。

几种垃圾回收机制(算法):

a.标记-清除算法

        从根节点开始标记所有可达对象,其余没标记的即为垃圾对象,执行清除,但是回收后的空间是不连续的。

b.标记-清除-压缩算法

       与标记-清除算法有相同的标记过程,第二阶段把标记的对象复制到新域中以便压缩堆栈。

c.复制算法

      将内存分为两块,每一次只使用一块,垃圾回收时,将标记对象复制到另一块中,然后完全清除原来使用的那块内存,复制后的空间是连续的。

d.分代算法

     这种算法将堆栈分为两个或多个域,用以存放不同寿命的对象。JVM生成的新对象一般放在其中的某个域中,过段时间,继续存在的对象将获得使用期并转入更长寿的域中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息