|
方法区(永久代,类似堆,存放编译后的常量,静态变量), 堆,虚拟机栈,本地栈,程序计数器
对象访问定位, 句柄池在java 堆中, 栈中的 reference去找堆中的句柄池里的对象指针,让后再去找实例对象和方法区里的类型数据。好处是GC不会改变栈中reference,
直接通过指针访问,java堆的实例,实例对象里保存这对象实例类型数据的指针。好处是快
1.堆内存溢出主要是因为对象过多
2.虚拟机栈内存溢出,本地方法栈内存溢出,主要是因为,线程请求的栈深度大于虚拟机所允许的最大深度。
虚拟机在扩展栈时无法申请到足够的内存空间。
3.引用计数算法 -
可达性分析算法:判断对象的引用链可否到达
4.标记清除算法,不是很好,这样回收后造成大量不连续的内存碎片,在要分配大对象的时候找不到合适的内存地址。、
5.复制算法,将内存一分为二,在第一部分用完了,就清理一次,把剩下的复制到2号内存,然后清理1号内存里的所有,然后循环使用。缺点就是将内存缩小了一半
6.标记整理算法,跟标记清除算法类似,只是多一个步骤,就是整理,将需要清除的和不需要清除的向相反方向移动,然后清楚边界意外的那些内存
分代收集算法,就是根据堆中的新生代和老年代,采用恰当的算法去实现,例如,新生代用 复制算法,老年代用 标记整理算法。
7.class加载,把一个类的全限定名来获取定义此类的二进制字节流,将这个字节流所代表的静态存储结构化为方法区的运行时数据结构,在内存中生成一个代表这个java.lang.class的对象,作为方法区这个类的各种数据访问的入口
验证:验证 cafebabe 版本号是否是该VM允许,常量池中的常量是否有不被支持的常量类型.........
这个类是否有父类,是否实现了接口里的方法,
保证数栈的数据类型与指令代码序列都能配合工作 , 不会出现放置一个int数据,使用的却按 long类型来加载入本地变量
符号验证,比如 private protect 等字段,方法的访问性。
准备:正式为类变量分配内存,和初始值的阶段,都会分配到方法区中。且此时只是定义一个 static 变量,不会赋值,只会让 变量 = 0值。赋值要等到初始化阶段才执行。
只有final 变量 才会在此时赋值;
解析:是虚拟机将常量池内的符号引用替换为直接引用的过程,判断C是都是数组类型,如果不是直接加载,如果是,首先会加载数组类型,然后添加数字元素的类型。
初始化:最后阶段了,初始化变量的值,静态语句块
启动类 加载器 Bootstrap,负责加载<JAVA_HOME>\lib目录中的类库到虚拟机内存中。扩展类加载器
APP ClassLoader是我们通常使用的默认的类加载器。
|