Earyant的技术博客

欢迎来到Earyant的技术博客,在这里我将与你分享新技术。

JVM介绍

JVM介绍

JVM包括:

* 1、 字节码指令集
* 2、 一组寄存器
* 3、 一个栈
* 4、 一个垃圾回收堆
* 5、 存储方法区

JVM 的生命周期

1) JVM 实例对应了一个独立运行的 java 程序它是进程级别
1) 启动。启动一个 Java 程序时,一个 JVM 实例就产生了,任何一个拥有 public static void main(String[] args) 函数的 class 都可以作为 JVM 实例运行的起点
2) 运行。main() 作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM 内部有两种线程:守护线程和非守护线程,main() 属于非守护线程,守护线程通常由 JVM 自己使用, java 程序也可以表明自己创建的线程是守护线程
3) 消亡。当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用 Runtime 类或者 System.exit() 来退出

2) JVM 执行引擎实例则对应了属于用户运行程序的线程它是线程级别的

JVM模型

image

内存空间:

1) 方法区: 指令计数器以及其他隐含寄存器
2) Java堆: 
3) Java栈:
4) 本地方法栈:

共享不共享:

共享:
    1) 方法区
    2) 栈(Heap)
不共享:
    1)程序计数器
    2)VM stack 虚拟机栈
    3)本地方法栈


1) 程序计数器: 
2) 栈: 线程私有的,每个线程创建的同时都会创建 JVM 栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及 Stack Frame,非基本类型的对象在 JVM 栈上仅存放一个指向堆上的地址。
3) 堆:1)存储 *对象实例以及数组值*
       2)**!Sun Hospot JVM为了提高对象内存分配的效率,对于所创建的线程都会分配一个独立的空间TLAB(Thread Local Allocation Buffer) ,其大小由JVM根据运行的情况计算而得,在TLAB中分配的对象不需要加锁,因此JVM在给线程的对象分配内存时会尽量在TLAB中分配,性能和C性能差不多高效,如果对象过大,仍然直接在堆中分配。 **
       3)TLAB仅作用于新生代的Eden Space,因此多个小对象比一个大对象高效。
       4)新创建的对象总是被放在新生代中,如果在一次或者多次GC后活下来,就会被转移到老年代。
4)方法区:1)在Sun JDK中对应着为永久带、持久带 !!!
           2)方法区存放了所加载类的信息(名称,修饰符等),类中的静态变量,类中定义为final类型的常量,类中的Field信息,类中的方法信息,当开发人员用Class对象的getname,isInterface等获取信息时,数据都来源于方法区,方法区也是**共享的**,在一定条件下,也会被GC,当方法区使用的内存超过其允许的大小,也会抛OutMemory异常。

原因:

JVM每遇到一个线程,都会为其分配一个程序计数器,VM stack 和本地方法栈,当线程终止时三者所使用的空间也被回收掉。

欢迎关注我的其它发布渠道