1.内存管理
[图片上传失败...(image-50a31-1592738472169)]
1.1程序计数器
线程私有,Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的。
所以在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。
因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储。这样的现在我们称这类内存区域为"线程私有"的内存。
1.2.Java虚拟机栈
线程私有,每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程,用于存储局部变量表、操作栈、动态链接、方法出口等信息,
局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)
1.3.本地方法栈
本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务,
1.4 java堆
线程共享,Java虚拟机管理的内存中最大的一块,所有的对象实例以及数组都要在堆上分配。Java堆是垃圾收集器管理的主要区域,Java堆可以处于物理上不连续的内存空间中,只要逻辑上联系即可,无法扩展是抛出outofmemoryerror
1.5 方法区
线程共享,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。
1.5.1 运行时常量池
方法区的一部分,class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符合引用,
2.垃圾收集器
2.1垃圾收集算法
2.1.1可达性分析算法
通过一系列的称为 GC Roots 的对象作为起始点,从这些节点开始向下搜索,搜索说走过的路径称为引用链,当一个对象到GC Roots 没有任何引用链相连时。证明该对象是不可用,判定为可回收的对象。
[图片上传失败...(image-7cbacd-1592738472169)]
如图 3-1所示 对象object 5 object6 object7虽然相互关联,但他们到GC Roots是不可达的,所以他们将会被判为是可回收的对象。但并不是“非死不可”的,还有其他种种判断。
2.2.1 标记-清除算法
首先标记出所有需要回收的对象,在标记完成后统一回收所有标记的对象,
[图片上传失败...(image-42c230-1592738472169)]
主要不足有两个:一是效率问题,标记和清除两个过程的效率都不高:另一个是空间的问题,标记清除之后产生大量的不连续的内存碎片,控件碎片太多可能导致以后再程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
2.2.1 复制算法
它将可用内存按容量分为相等的两块,每次只使用其中的一块,当这一块内存用完,就将还存活的对象复制到另一块上面,然后再将已使用过的内存空间一次清理掉,这样使得每次都对整个半区域进行内存回收,内存分配时也不用考虑内存碎片,只要一动堆顶指针。
[图片上传失败...(image-f303b1-1592738472169)]
缺点将内存缩小了原来的一半。
2.2.1 标记-整理算法
[图片上传失败...(image-981d80-1592738472169)]
让所有存活的对象都像一端移动,然后直接清除掉端边界以外的内存。
2.2.1 分代搜集算法
根据对象存活周期的不同将内存分为几块,一般把Java堆分为新生代和老年代,新生代每次垃圾回收都有大批对象死去,少量存活,使用复制算法,老年代因为对象存活率高,没有额外空间,就必须使用 “标记-清除” 或者 “标记-整理” 算法进行回收。
3.类加载过程
3.1 类的加载过程
mahua3.1.1 加载
-
通过一个类的全限定名来获取定义此类的二进制字节流
-
将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
-
在内存中生成一个代表这个类的Java.lang.Class 对象,作为方法区这个类的各种数据的访问入口
3.1.2 连接
1.验证
1.文件格式验证
2.元数据验证
3.字节码验证
4.符号引用验证
2.准备
准备阶段是正式为类变量分配内存并设置类变量初始值得阶段,这些变量所使用的内存都将在方法区中进 行分配。这时进行内存分配的仅包括被 static 修饰的变量,不包含实例变量,实例变量将会周期对象实例化 时随着对象一起分配在Java堆中
3.解析
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,
类或者接口的解析
字段解析
类方法解析
接口方法解析
4.初始化
类初始化阶段是类加载过程的最后一步,开始真正执行类中定义的Java程序代码,准备阶段,变量已经赋过一次系统要求的初始值,这个阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源,
4 类加载器
对于任意一个类,都需要有加载他的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,所以只要他们的类加载器不同,那这两个类就必定不相等,
1 双亲委派模型
从Java虚拟机的角度来讲,只存在两种不同的类加载器,一种是启动类加载器(bootstap classLoader),这个类加载器使用c+++实现,是虚拟机自身的一部分,另一种就是所有其他的类的加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,并且都继承自抽象类,Java.lang.ClassLoader。
绝大部分都会使用到以下3种系统提供的类加载器
image
网友评论