以下内容源于个人对《深入java虚拟机》的理解总结
基本概念:
java虚拟机可以指一种抽象规范,也可以指一种具体实现,亦可以指一个java虚拟机实例。
虚拟机生命周期:
一个java虚拟机实例的天职是:负责运行一个java程序。当启动一个java程序时,一个虚拟机实例诞生。程序关闭退出,虚拟机实例亦随之消亡。如果在同一台计算机上运行三个java程序,将得到三个java虚拟机实例。每个java程序都运行与它自己的java虚拟机实例中。
一个java虚拟机实例通过调用main()方法来运行一个java程序。
垃圾收集 垃圾收集器的主要工作就是自动回收不再被运行的程序引用的对象所占的内存。此外它也可能去移动那些还在使用的对象,以此减少碎片。
在谈论垃圾回收前,首先了解下java虚拟机的内部体系结构,如下图所示
中间虚线框部分为运行时数据区域,由5部分组成,分别为方法区,堆,栈,程序计数器及本地方法栈。
1.程序计数器
对于一个运行中的java程序而言,其中每一个线程都有自己的PC寄存器,它是该线程启动时创建。
它的作用可以看做当前字节码执行的位置指示器。
2.本地方法栈
任何本地方法接口都会使用本地方法栈。当线程调用本地方法时,虚拟机会创建一个新的栈帧并压人java栈,然而当它调用的是本地方法时,虚拟机会保持java栈不变,不再在线程的java栈中压人新的帧。虚拟机只是简单的动态连接,并直接调用指定的本地方法。
3.方法区
在java虚拟机中,关于被装载类型的信息存储在一个逻辑上被称为方法区的内存中。类变量(静态变量)也是存储在方法区。方法区是线程共享的,必须被设计为线程安全的。
4.java栈
当启动一个新线程时,java虚拟机都会为它分配一个java栈,java栈以帧为单位保存线程的运行状态。虚拟机只会直接对java栈执行两种操作:以帧为单位的压栈和出栈。
某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。
当线程执行一个方法时,它会跟踪当前类和当前常量池。
java栈上的所有数据都是线程私有的,任何线程都不能访问另一个线程的栈数据,因此不需要考虑多线程下栈数据的访问同步问题。
5.java堆
java程序在运行时创建的所有类实例和数组都放在同一个堆中。每个java程序独占一个虚拟机实例----它们不会互相干扰,而一个java虚拟机实例中只存在一个堆空间,所有线程都共享这个堆,这种情况下,必须考虑多线程情况下堆数据的同步问题。
java类性的生命周期
一个java的装载、连接、初始化见下图:
类被初始化后就可以使用了,程序可以访问它的静态字段,调用它的静态方法,或者创建它的实例即对象。
类被实例化有4中途径:1.显式的new 2.Class,或Construtor对象的newInstance()方法;3 . 调用任何现有对象的clone()方法 4.ObjectInputStream.getObject()方法反序列化。
一个对象一旦不再被引用,就需要进行垃圾收集。至于how,when进行垃圾收集,取决各虚拟机实现。下面介绍常见hotSpot虚拟机的垃圾回收机制。