java虚拟机JVM

 

类装载器的分类(ClassLoader):           ①BootStap,根装载器
(类装载器负责加加载class文件,class     ②ExtClassLoader,扩展类装载器
 文件在开头 有特定的文件表示)               ③ApplicationClassLoader,应用类装载器 
                                                                 ④自定义装载器
 
双亲委派机制:当一个类收到类加载请求,他首先不会尝试本身去加载这个类,而是把这请求委派给父类去完成,每个层次类加载器都是如此,所以全部的加载请求都应该传送到启动类加载器中,只有当父类加载器反馈本身没法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试本身去加载。
 
沙箱安全机制:沙箱机制就是将Java代码限定在虚拟机(JVM)特定的运行范围中,而且严格限制代码对本地系统资源访问,经过这样的措施来保证对代码的有效隔离,防止对本地系统形成破坏。
(1)类加载器:①它防止恶意代码区干涉善意的代码②它守护了被信任的类库边界③它将代码纳入保护域,该域决定了代码能够进行哪些操做
(2)Class文件检验器:Class文件检验器保证装载的class文件内容的内部结构的正确,而且这些class文件相互协调一致。Class文件检验器实现的安全目标之一就是程序的健壮性,JAVA虚拟机的class文件检验器要进行四趟扫描来文成他的操做(第一趟:在装载字节序列的时候进行,这个是校验class文件结构的合法性;第二趟:扫描发生在方法区中,主要对于语义、语法和词法的分析;第三趟:字节码校验字节码流=操做码+操做数;第四趟:符号引用的校验)
 
Execution Engine执行引擎:负责解释命令,提交操做系统执行。
 
Native Interface本地接口:做用是融合不一样的编程语言为Java所用,在内存中开辟了一块区域处理标记为native的代码,具体作法是Native Method Stack中登记native方法,在Execution Engine执行时加载native libraies,在企业级应用中已经比较少见,
 
Native Method Stack:具体作法是Native Method Stack中登记native方法,在Execution Engine执行时加载本地方法库。
 
Program Counter Register(PC计数器):每一个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来储存指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个很是小的内存空间,几乎能够忽略不记。它是当前线程所执行的字节码的行号指示器,字节码解释器经过改变这个计数器的值来选取下一条须要执行的字节码指令。若是执行的是一个Native方法,这个计数器是空的。
 
Method Area(方法区):供各线程共享的运行时内存区域。它储存除了每个类的结构信息,例如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容。还储存静态方法、静态内部类和静态变量(static);
方法区是规范,在不一样的虚拟机里面实现是不同的,最典型的就是(PermGen space)永久代和以(Metaspace)元空间
 
栈管运行
堆管存储
 
Stack栈:储存的是8种基本类型的变量、对象的应用变量和实例方法。
即①本地变量:输入参数和输出参数以及方法内的变量
   ②栈操做:记录出栈、入栈的操做
   ③栈帧数据:包括类文件、方法等
栈运行遵循“先进先出”、“后进后出”原则
每一个方法执行的同时都会建立一个栈帧,用于存储局部变量表、操做数栈、动态链接、方法出口等信息,每个方法从调用直至执行完毕的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程/栈的大小和具体JVM有关,一般在256k-756k之间,约等于1mb。
 
经过指针的方式来访问对象,栈中存放基本数据类型以及应用变量,指向堆中存放的实例对象,java堆中存放访问类元数据的地址,方法区中存放对象的类的类对象
 
Heap(堆):一个JVM实例只存在一个堆内存,堆内存的大小是能够调节的,类加载器读取了;类文件后,须要把类、方法、常变量放到堆内存中,保存全部引用类型的真实信息,以方便执行器执行。
新生区:是类的诞生、生长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。新生区又分为两部分:伊甸区(Eden space)和幸存者区(Survicor space),全部的类都是在伊甸区被new出来的。幸存区有两个:0区(Survivor 0 space)和1区(Survivor 1 space).当伊甸园区的空间用完时,程序又要建立对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的再也不被其余对象所引用的对象进行销毁。而后将伊甸园中的剩余对象移动到幸存者0区,若幸存者0区也满了,再对该区进行垃圾回收,而后移动到1区,1区满了,移动到养老区。若养老区也满了,那么这个时候将产生Major GC(FullGC),进行养老区的内存清理。若养老区执行了Full GC后依然没法进行对象的保存,就会产生OOM异常“OutOfMemoryError”。
若是出现java.lang.OutOfMemoryError:Java heap space 异常,说明Java虚拟机的堆内存不够。缘由有二:(1)Java虚拟机的堆内存设置不够,能够经过参数-Xms、-Xmx来调整
                 (2)代码中建立了大量大对象,而且长时间不能被垃圾收集器收集(存在被引用)
 
 
MinorGC的过程(复制 -> 清空 -> 互换)
堆内存中,新生代和老年代的比例为1/3和2/3
 
1:eden、SurvivorFrom 复制到 SurvivorTo,年龄+1
在新生代中,Eden所占比例为8/10,幸存者0区和幸存者1区的比例至关,为1/10
Eden满的时候,出发第一次GC,将活着的对象拷贝到from区,清空Eden区,存新的对象,放Eden再次触发GC的时候会扫描Eden区和From区,对这两个区进行垃圾回收,通过此次回收还存活的对象,会直接复制到To区(若是有对象的年龄已经达到了老年的标准,复制到老年区),同时把这些对象的年龄+1.
2:清空 eden、SurvivorFrom
From和Eden中的数据复制到To中后,发生交换,From为空,转为To,To转为From
3:SurvivorTo和 SurvivorFrom 互换 
最后,SurvivorTo和SurvivorFrom互换,原SurvivorTo成为下一次GC时的SurvivorFrom区。部分对象会在From和To区域中复制来复制去,如此交换15次(由JVM参数MaxTenuringThreshold决定,这个参数默认是15),最终若是仍是存活,就存入到老年代
 
方法区(Method Area)和堆同样,是各个线程共享的内存区域,它用于存储虚拟机加载的:类信息+普一般量+静态常量+编译器编译后的代码等等,虽然JVM规范将方法区描述为堆的一个逻辑部分,但它却还有一个别名叫作Non-Heap(非堆),目的就是要和堆分开。
jdk1.7的版本中,已经将本来放在永久代的字符串常量池移走。
java7以前的永久区,是一个常驻内存区域,用于存放JDK自身所携带的Class,Interface的元数据,也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭JVM才会释放此区域所占用的内存。
 
Java8以后将永久代取消了,由元空间取代。本质和永久代相似。最大的区别在于:永久代使用的JVM的堆内存,可是Java8后的元空间并不在虚拟机中,而是使用本地物理内存。
 
JVM调优
-Xms初始分配大小为:物理内存的1/64
-Xmx最大分配内存为:物理内存的1/4
VM参数:    -Xms1024m -Xmx1024m -XX:+PrintGCDetails
 
相关文章
相关标签/搜索