1、JVM位置
JVM是运行在操作系统之上的,它与硬件没有直接交互,所以与硬件没关系。JVM有Sun公司的HotSpot;BEA的JRockit;IBM的J9VM。前面两个都被Oracle收购了。
2、JVM逻辑架构图
分为上中下三部分。Class files在文件的首行有响应的标识,表名文件时class文件。
类加载器:
虚拟机自带的
1、Bootstrap 启动类加载器 加载C 、C++
2、Extension 扩展类加载器 加载Java
3、应用程序类加载器(系统类加载器) AppClassLoader 加载Java
用户自定义的
自定义加载器,Java.lang.ClassLoader的子类。
本地方法栈
标记为native的方法,只有签名,没有实现体,由C或C++实现。
本地方法接口
native标记的方法想要执行,则需要通过本地方法接口调用C。
本地方法库
操作Mysql则需要Mysql驱动代码;操作redis需要Jdeis。
程序计数器(PC寄存器)
用来存储下一条指令的地址。
方法区(共享区间) 会有垃圾回收,但是主要在于堆上,因为对象比较占内存。
是被所有线程共享。静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中。
栈(stack):先进后出
对于栈来说不存在垃圾回收问题,只要线程一结束该栈就Over,生命周期和线程一致,是线程私有的。它存放:8种基本数据类型+对象的引用变量+实例方法都是在函数的栈内存中分配的。
堆(heap) 垃圾回收器,主要回收的地方。
所有的对象实例都存放在堆内存上。Java7及以前,堆逻辑上分为三个部分,新生区、养老区、永久区;物理上永久区不再堆上,根据jdk版本有所不同,jdk8把永久区称作元空间。
新生区,是类的诞生、生长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。新生区又被分为两个部分:伊甸园(Eden space)和幸存者区(Survivor pace),所有的类都是在伊甸园区被new出来的。幸存区有两个:0区(Survivor 0 space)和1区(Survivor 1 space)。当伊甸园的空间用完时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。然后将伊甸园中的剩余对象移动到幸存0区。若幸存0区也满了,在对该区进行垃圾回收,然后移动到1区。那如果1区也满了呢?再次垃圾回收,满足条件后移动到养老区。若养老区也满了,那么将产生MajorGC(FullGC),进行养老区的内存清理。若养老区执行了Full GC之后依然无法进行对象的保存,就会产生OOM异常:OutOfMemoryError.
java虚拟机出现OOM的错误,原因主要有两个:
(1)Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。
(2)代码中创建了大量大对象,并且长时间不能被垃圾回收器收集(存在被引用)。