jvm
一.运行时数据区
1.线程共享和线程私有:
01.线程共享:
堆,方法区
02.线程私有:
虚拟机栈,本地方法栈,程序计数器
2.程序计数器
当前线程执行字节码文件的行号指示器
能够在线程切换之后,找到自己正确的位置
是唯一一个不会导致内存泄漏(OutOfMemory,OOM)的区域
3.虚拟机栈:
基本数据类型的变量和对象的引用变量都存在此区域;
遵循“先进后出,后进先出”
StackOverFlowError:
线程请求的栈深度大于了虚拟机规定的最大深度
OutOfMemoryError:
虚拟机在扩展栈时,无法申请到足够的内存空间!
4.本地方法栈
主要服务于Native修饰的方法
在HotSport中虚拟机栈和本地方法栈合为一体
堆:
所有对象的实例和数组开辟空间都在此区域保存!
所有线程共享
GC主要回收对象的区域
1.堆分区:新生代,老年代,永久代
2.方法区(静态去)
所有线程共享;
方法(包含构造函数),接口 定义在此区域;
所有方法的信息
静态变量+常量+类信息+方法信息+常量池
二.类的生命周期:
类的生命周期从类被加载,连接和初始化开始到类的卸载结束
01.类的生命周期中,类的二进制位于方法区;
02.在堆中会有一个描述这个类的Class对象;
2.1加载将class字节码文件内容加载到内存中,并将这些静态数据转换成方法区中运行时数据结构,在堆中生成一格Class对象;这个Class对象就是方法区类数据的访问入口
2.2链接
0.1类的验证
001.类文件的结构检查
002.语义检查 比如说final修饰的变量在编译期间发现再次赋值
003.字节码验证,确保字节码能被jvm识别
0.2类的准备
为类中所有static修饰的内容开辟空间,并赋予初始值!!
static int num=100;
这时候 num=0;
0.3类的解析
符号引用:就是用字符串的形式来表示某个变量或是类,我们能看懂String a="a"; Student stu=new Student();
直接引用:是根据符号引用翻译出来的地址!
2.3 初始化
加载不是初始化
初始化指的是实例化!创建出类的实例!
初始化的时机
01.类的主动引用
001.new一个类的对象
002.通过反射的newInstance();
003.再初始化子类时候必须先初始化父类
02.类的被动引用
001.通过类名访问静态内容
002.调用类的静态常量也会不会初始化类
003.用类作为对象数组存在时,也不会初始化类
004.子类调用父类的静态变量不会加载子类的静态代码块(不会执行类的准备阶段)
JVM垃圾回首机制
一.垃圾回收机制(GC)
1.1:为啥需要垃圾回收机制
01.只要是对象被创建,那么就会在虚拟机的堆中开辟空间;
02.程序运行过程中会创建N个对象,美哥对象都会有自己的空间;
03.如果每个对象都永久的占领这块空间,显然内存是不够的
总结:为了保证其他对象能够被正确的创建!!
在C语言中,垃圾回收的任务是程序员自身负责的
可能会出现的问题:
01.由于程序猿粗心大意,导致煤油及时释放不使用的对象,释放错误!
02.程序猿一旦释放了程序核心对象(比如说系统对象),系统崩溃!
1.2:垃圾回收机制的定义
在java程序运行过程中,jvm有一个专门负责回收那些不再使用的对象
所占的内存,这种回收的过程,我们称之为垃圾回收机制(GC,Garbage Collection)
1.3:垃圾回收机制的特点
01.减轻了程序猿进行内存管理的负担
02.防止系统内存被非法释放,使我们的程序更加健壮
03.只有在对象不被任何变量引用时,才能被回收
04.程序无法让垃圾回收机制强行回收垃圾操作
05.当垃圾回收机制将要回收不用的对象内存时,会先调用这个对象的finalize()
这个方法可能使对象复活,导致垃圾回收器取消对该对象的回收。:
1.4:对象的状态
在虚拟机的垃圾回收器来看,堆中所有的对象都有三种状态!
01.可触及状态
02.可复活状态
03.不可触及状态
直邮对向出于不可触及状态的时候,垃圾回收机制真正的释放对象所占有的内存