JVM回收
方法区的垃圾回收
主要回收的是信息类
判断一个类型是否被废弃,需同时满足三个苛刻条件:
1.该类的所有实类都已经被回收
*2.加载该类的类加载器也被回收了
3.该类的的class对象也不再被使用了
线程共享:堆(存对象,大)方法
线程私有:程序计数器,虚拟机栈,本地方法栈
会出现的内存溢出:堆,方法,虚拟机栈,本地方法栈
会出现的垃圾回收:堆,方法区
HashMap,面向对象5min
本地方法接口
虚拟机中负责调用本地方法的入口,本地方法运行在本地方法栈中。
本地方法定义:被native修饰的方法,没有方法体,是操作系统提供方法
为什么java里要调用本地方法
java没有权限直接访问计算机硬件,需要调用本地操作系统方法
执行引擎(黑盒)
主要负责将加载到虚拟机中的字节码编译为虚拟机中的机器码
.java----编译------》.class 在开发阶段(前端编译)
.class----执行引擎编译----》机器码 在运行阶段
1.引擎是JAVA虚拟机核心的组成部分之一
2.
解释器/JIT编译器?
解释器/解释执行----》sql,html,css,js,python解释执行(一行一行执行),不需要整体编译。
解释执行特点:速度慢,不需要花费时间翻译
编译执行,先把代码整体进行编译,生成另一种文件格式
编译执行特点:编译后执行快,但是编译一定时间
jvm中的执行引擎再将字节码翻译为机器码时,采取半解释,半编译机制
开始时,可以采用解释执行,立即投入到翻译工作里
等到编译器编译完成后,采用编译执行
垃圾回收
JAVA语言的特点
开源,跨平台,面向对象,自动回收垃圾,线程,网络。。。
概述
垃圾对象定义:在运行程序中没有任何引用指向的对象(容易导致内存溢出)
早期垃圾回收C/C++
malloc()申请空间
free()释放空间
应该关心哪些区域的回收
堆(重点):频繁回收young区
较少收集old区
方法区不回收
内存溢出与泄露
内存溢出
简称OOM,指内存空间不足以运行程序,会报出内存异常(out of memery)
e.g.
单例模式,一些需要close的资源
内存泄漏
也称存储渗漏,对象不会再被用到了,但是GC(回收器)却仍然不回收该对象,一直悄悄的占用内存资源
e.g.提供close()方法关闭资源的对象
数据库连接对象,网络Socket,IO读取文件的对象
垃圾回收相关算法(判断对象是否为垃圾)
垃圾标记阶段算法
目的:将堆内存的对象进行检查,检查对象有没有被引用指向。
标记阶段涉及两个算法:引用计数算法(现在虚拟机已经不再使用)
可达性分析算法
引用技术算法
思想:在每个对象中设置一个字段来记录引用的数量,有一个引用指向对象,计数器加一,一 旦有引用断开,计数器减一;
优缺点:实现思路简单
计数器字段占用空间加一减一是需要开销的
重点是不能解决循环引用问题,A,B,C 三个对象之间相互关联引用,但是可能与外界没 有联系,外界不可能引用A,B,C三个对象,造成内存泄漏
Hello h1=new Hello(); 引用计数器()
Hello h2=h1;
h1=null;
h2=null;
可达性分析算法(跟搜索算法,追踪性分析算法)
思想:从一些活跃对象开始进行搜索,只要跟根对象有联系的对象,就不是垃圾对象,
与根对象没有任何联系的,即使是对象之间存在引用关系,也可判定为垃圾对象
那些对象可以作为根对象:
1.虚拟机栈中引用的对象
2.类中的一些静态成员变量
3.与同步锁有关的对象
4.虚拟机内部的一些Class类,异常类,类加载
final finally{ } finalize( )
Object类中的finalize()
protected void finalize() throws Throwable{ }
finalize( )在对象被判定为垃圾后,在对象被真正回收之前由虚拟机自动调用,
在finalize()中执行一些最后要执行的功能,
finalize()只被执行一次
允许在子类被重写,用于在对象回收时的资源释放
由于finalize()存在,对象可以分为三种状态:
可触及:有引用指向的对象
可复活的:已经判定为垃圾对象。但是finalize()方法还没有执行过,有可能在finalize()复活
不可触及的:finalize()已经执行过了,并且又被判定为垃圾了。
垃圾回收阶段算法
标记-复制算法
将内存分为两块,把正在使用中的内存块的存货对象,复制到零一块内存中,从内存块的开始位置摆放,然后清除正在使用的内存块。
适合存活对象少,垃圾对象多的场景,适合新生代的回收。
标记-清除算法
不移动存活对象,将垃圾对象的地址记录在一个空闲列表中,有新对象到来时,可以吧新对象飞配到空闲列表中的内存地址上,覆盖垃圾对象。
适合老年代回收因为存货多且大,不需要移动对象。
标记-压缩算法
将存活对象会压缩到内存的一端,重新排列,将边界外的空间进行清理,以减少内存碎片。
也是适用于老年代。
垃圾回收器
标记阶段算法和回收阶段的算法都是方法论,垃圾回收器是真正的实践者。
不同的JDK版本中提供不同的垃圾收集器
垃圾收集器分类
从线程数量分:单线程垃圾收集器,只有一个线程进行垃圾回收
多线程垃圾收集器,有多个线程同时进行垃圾回收
从工作模式分:独占式垃圾收集器,当垃圾收集线程执行时,其它程序线程会暂停执行
并发式垃圾收集器,当垃圾收集线程执行时,其它程序线程会正常执行
从回收的内存空间分:新生代的垃圾收集器,老年代的垃圾收集器
什么是面向对象,你对JAVA语言的认识
6G1(Garbage First)回收器
现在程序业务越来越复杂,没有GC就无法正常运行
G1垃圾回收器是当今收集器技术发展最前沿的成果之一。
G1是一个并行回收器,它把堆内存分割为很多不相关的区域(物理上不连续逻辑上连续)。
G1是面向对象的垃圾回收器,也继承了cms中垃圾回收集线程和用户线程同时执行的特点。
G1垃圾回收器可以做到对整个堆进行回收,不再分老年代,新生代。
垃圾回收性能高
为什么叫G1(垃圾优先)
把每个分区(新生代,老年代)又分为若干个小的区域,会对每个小的区域进行跟踪优先回收垃圾最多的区
查看和设置虚拟机中的垃圾回收器
方法区大小可调
在控制台打印正在使用的垃圾回收器:-XX:+PrintGCDetails -version
对垃圾回收的年龄:默认是15次
设置垃圾回收器
为什么要学习jvm,学习jvm有什么好处
可以更好的帮助我们理解java程序运行过程(类加载,运行时数据区(堆)),垃圾回收
对我们编写java程序都有指导作用
如何学习(书 深入理解java虚拟机)