jvm是java的虚拟机,所有的java程序都必须运行在jvm上面。
jvm是java的解释器,java程序编译成class文件后,装载入jvm中运行,jvm将class字节码解释为平台的机器码,平台执行机器码。
jvm是进程级别,main()方法对应一个jvm进程。从java进入main()方法开始,jvm进程激活。
一、jvm运行过程
1、加载class文件;
2、分配内存;
3、解释字节码成机器码;
4、运行过程垃圾收集;
5、结束。
如图所示:
二、jvm结构
1、类装载器(ClassLoader)
2、执行引擎(执行字节码)
3、运行时数据区(方法区、堆、栈、pc寄存器、本地方法栈)
如下图:
三、jvm运行时数据区
1、pc寄存器
pc寄存器用于存储每个线程下一步将要执行的jvm指令,如果该方法为native,则pc寄存器不存储任何信息;
2、jvm栈
jvm栈是线程私有的,每个线程创建的同事都会创建jvm栈,jvm栈中存放的是当前线程中局部基本类型的变量(java定义的八种基本类型:boolean、char、byte、int、short、long、double、float)、部分的返回结果以及Stack Frame,对象在jvm栈上存放一个指向对象堆的指针
3、堆(heap)
它是jvm用来存储对象实例和数组的区域,可以认为java中所有通过new创建的对象都保存在这里。Heap中保存的对象需要GC进行动态回收。
(1)堆是jvm中所有线程共享的,因此堆内对象内存的分配都需要进行加锁,这导致了new对象的开销比较大。
(2)sun Hotspot JVM未了提升对象内存分配的效率,对于创建的线程都会分配一块独立的空间TLAB(Thread Local Allocation Buffer),其大小由JVM根据运行情况计算得到,在TLAB上分配对象不需要进行加锁,因此JVM给对象分配内存时尽量在TLAB上分配,如果对象多大,则仍然会直接分配在堆的共享内存上。
(3)TLAB仅作用于新生代的Eden Space,因此编写java程序时,通常多个小对象比大对象分配内存更高校。
(4)所有新创建的Object都将会存储在新生代Young Generation中。如果Young Generation
中的数据在一次或者多次GC后存活下来,将被转移到OldGeneration。
4、方法区域(Method Area)
(1)在sun JDK中这块区域对应的PermanetGeneration,成为持久代;
(2)方法区域存放了所有加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义的final类型的常量、类中的Field信息、类中的方法信息。当开发人员在程序中通过Class对象中的GetName、isInterface邓方法获取信息,这些数据就是来源于方法区域,同时方法区域也是全局共享的 ,在一定条件下也会被GC。
5、运行时常量池(Runtime constant Pool)
存放类中固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。
6、本地方法栈(native Method Stacks)
JVM采用本地方法栈来支持native方法执行,此区域用于存储每个native方法调用状态。