JAVA:Java分为Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)
JVM:Java Virtual Machine(Java虚拟机)的缩写。
Java运行机制:
Java源码-编译器-字节码文件-JVM-机器码
jvm版本:
1.7以前:Sun下的HotSpot(主流)、BEA下的JRockit、IBM下的J9 JVM
1.8:集成sun的HotSpot和BEA下的JRockit=>JVM
JVM结构:
class loader(类装载器):负责加载.class文件,不运行。
Runtime Data Area(运行时数据区):用以储存Java运行时的各种数据,对象、变量等。分为方法区,虚拟机栈,本地方法栈,堆,程序计数器
Execution Engine(执行引擎):执行包在装载类的方法中的指令,也就是方法
Native Interface(本地接口):调用其他语言方法,基本报废
Runtime data area 运行数据区
主要分为方法区(Method Area),虚拟机栈,本地方法栈,堆(Heap),程序计数器
JVM调优主要就是优化 Heap堆 和 Method Area 方法区
方法区(Method Area)
1.方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间。
2.静态变量,常量,类信息(构造方法/接口定义),运行时常量池存在方法区中;但是实例变量存在堆内存中,和方法区无关。
栈(Stack)
栈也叫栈内存,主管Java程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束该栈就Over,生命周期和线程一致,是线程私有的。
堆(Heap)
分三个区域:新生区(伊甸区、幸存0区、1区)、养老区、永久存储区
新生区:类的诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命
养老区:用于保存从新生区筛选出来的 JAVA 对象,一般池对象都在这个区域活跃
永久存储区:存放JDK自身所携带的 Class,Interface 的元数据,是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭 JVM 才会释放此区域所占用的内存。
所有对象都在伊甸区被new出来,
当伊甸区不够用时,GC进行回收,并将剩余对象移动到幸存0区。这一步叫Minor GC
当幸存0区也满了,GC进行回收,并移动剩余对象到幸存1区。
当幸存1区也满了,GC回收后移动剩余对象到养老区。
当养老区满了,GC会对养老区进行清理。这一步叫Major GC又称FullGCC
若清理养老区后,还是无法进行对象的保存,此时发生OutOfMemoryError,俗称OOM,详细为java.lang.OutOfMemoryError: Java heap space
Java heap space异常说明堆内存不足,原因有二:1.jvm堆内存设置不够;2.代码创建了大量对象,并且对象一直有被引用到(GC不能回收)。
这里还有一种OOM异常:java.lang.OutOfMemoryError: PermGen space
PermGen space异常说明JVM对永久区设置的空间不够。原因有两种情况:1.程序启动时,加载了大量的jar包;2.大量通过动态反射生成的类不断被加载。
注:永久存储区,在JDK1.8以后,就取消掉了。