JVM启动流程java
JVM是Java程序运行的环境,同时是一个操做系统的一个应用程序进程,所以它有本身的生命周期,也有本身的代码和数据空间。 JVM工做原理和特色主要是指操做系统装入JVM,是经过jdk中Java.exe来完成,经过下面4步来完成JVM环境。算法
1.建立JVM装载环境和配置 JVM装入环境,JVM提供的方式是操做系统的动态链接文件数组
3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例 这样就能够在Java中调用JVM的函数了.调用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法得到JNIEnv结构的实例.安全
4.调用JNIEnv实例装载并处理class类。markdown
JVM基本结构架构
JVM体系主要是两个JVM的内部体系结构分为三个子系统和两大组件,分别是:类装载器(ClassLoader)子系统、执行引擎子系统和GC子系统,组件是内存运行数据区域和本地接口。函数
· 方法区(永久代) 方法区存储了每一个类的信息,好比类型的常量池、字段,方法信息、方法字节码。全部线程共享同一个方法区,所以访问方法区数据的和动态连接的进程必须线程安全。若是两个线程试图访问一个还未加载的类的字段或方法,必须只加载一次,并且两个线程必须等它加载完毕才能继续执行。spa
(JDK1.7中,已经把放在永久代的字符串常量池移到堆中。JDK1.8撤销永久代,引入元空间。元空间是直接存在内存中,不在java虚拟机中的,所以元空间依赖于内存大小。固然你也能够自定义元空间大小。) · 方法区不须要连续的内存,能够选择固定大小或者可扩展。而且还能够选择不实现垃圾收集。相对而言,垃圾收集行为在这个区域是比较少出现的,但并不是数据进入了方法区就如永久代的名字同样“永久”存在了。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载,通常来讲这个区域的回收“成绩”比较难以使人满意,尤为是类型的卸载,条件至关苛刻,可是这部分区域的回收确实是有必要的。当方法区没法知足内存分配需求时,将抛出OutOfMemoryError异常。操作系统
· 堆(Heap) 应用系统对象都保存在Java堆中,堆被用来在运行时分配类实例、数组。不能在栈上存储数组和对象。由于栈帧被设计为建立之后没法调整大小。栈帧只存储指向堆中对象或数组的引用。与局部变量数组(每一个栈帧中的)中的原始类型和引用类型不一样,对象老是存储在堆上以便在方法结束时不会被移除。对象只能由垃圾回收器移除。全部线程共享Java堆。线程
简述垃圾回收 为了支持分代垃圾回收机制,堆内存能够划分为新生代和老年代两个区域(默认新生代与老年代的空间大小为1:2)。新生代能够再划分为Eden区、From Survivor区和To Survivor区(三者比例为8:1:1)。几乎全部的新对象的建立都是在Eden区进行的。在垃圾回收(GC)过程当中,Eden中的活跃对象会被转移到Survivor区,当再到达必定的年龄(经历过的Minor GC的次数,每通过一次新生代回收,若是对象存活则它的年龄就加1,对象达到必定的年龄后),会被转移到老年代中。
· Java栈(Java Stack) Java栈是线程私有的内存区域,其中存储的是栈帧。,每一次方法调用建立一个帧,并压栈,调用完毕出栈。下面是内存的线程公有私有示意图:
通常由三部分组成:局部变量表、操做数据栈和帧数据区 局部变量表:能够存放的数据有8种基本数据类型(boolean,byte,char,short,int,float,long,double),对象引用和returnAddress类型。其中long和double由于是64位,会占用两个局部变量的空间。
操做数栈:主要保存计算过程的中间结果,同时做为计算过程当中的变量临时的存储空间。 下图是一个两数相加的操做数栈的过程:
栈上分配 小对象(通常几十个bytes),在没有逃逸的状况下,能够直接分配在栈上 直接分配在栈上,能够自动回收,减轻GC压力 大对象或者逃逸对象没法栈上分配
· 本地方法栈(Native Method Stack) 本地方法栈也是线程私有的内存区域,与java栈比较类似,不一样之处在于该区域主要是保存Native方法相关的数据。Native方法是非Java语言编写的方法。 与虚拟机栈同样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。
专一于Java架构师技术分享,撩我免费送Java全套架构师晋级资料 (Java架构师交流企Q鹅裙*/:445-820-*908 )