世界上并没有完美的程序,但我们并不因此而沮丧,因为写程序本来就是一个不断追求完美的过程。 ——摘自周志明

JVM体系结构

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)代码中创建了大量大对象,并且长时间不能被垃圾回收器收集(存在被引用)。

posted @ 2019-02-03 17:12  白杯与咖啡  阅读(227)  评论(0编辑  收藏  举报