类加载器与垃圾回收机制
目录索引
- 1.类加载器
- 1.1类生命周期
- 1.2三种类加载器
- 1.3类加载的特性
- 1.3.1类不会重复加载
- 1.3.2双亲委派机制
- 1.3.3沙箱安全机制
- 2.垃圾回收机制
- 2.1概念
- 2.2jvm运行时区
- 方法区
- 堆内存
- 虚拟机栈
- 本地方法栈
- 程序计数器
- 2.3堆内存空间
- 2.4垃圾收集算法
- 2.5垃圾收集器
1.类加载器
1.1类生命周期
1.2三种类加载器
如图所示,有三个类加载器。加载顺序从上至下,顺序寻找。也就是说当所有的父级加载器中找不到的时候,才会去子级中寻找
- BootstrapClassLoader:用于加载jre/lib中的jar包,这里都是java的核心类,且最核心包为 rt.jar
- ExtClassLoader:加载的是jir/lib/ext目录下的jar包,用于加载java的扩展类
- AppClassLoader:加载我们自己开发的类或项目开发用到的第三方jar包,位于我们项目的目录下,比如WEB-INF/lib目录。同时也会加载我们所写的程序。一般的,可以通过指令去查看对应的系统配置。
- 使用jps查看所有正在运行的java进程,使用jcmd可以查看对应进程的详细信息,最终可以找到一个VM.system_propertites的属性,里面会显示我们自己的类的具体位置。
1.3类加载的特性
1.3.1类不会重复加载
同一个类加载器的实例不会重复加载同一个类,可以通过代码验证(再循环外面定义一个类加载器,然后在循环里面不停地去尝试加载同一个类,会发现最终拿到的都是相同的结果,即使运行期间将原代码修改了),这里不具体展示了。
1.3.2双亲委派机制
注意这里的双亲不是指的父亲母亲,可以简单认为指的是儿子,父亲,爷爷这样一个关系。双亲委派模型又可以理解为败家子模型。
也就是说:当要去加载一个类的时候,会从下级不断的将加载的任务往上一级抛,看是否有加载器可以加载,直到最顶级的时候,如果没有一个表示能够加载,那么,就一级一级向下传导,让最低一级的加载器加载。
只有上级有任意一个加载器能够加载这个类,那么就会直接处理掉,不会让低级加载器去加载。
1.3.3沙箱安全机制
沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问
,那系统资源包括什么?——CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。
所有的Java程序运行都可以指定沙箱,可以定制安全策略。
组成沙箱的组件:
字节码校验器
:确保java类文件遵循java语言规范类装载器
- 它防止恶意代码去干涉善意代码(双亲委派机制)
- 它守护了不信任的类库边界
- 它将代码归入保护域,确定了代码可以进行的操作
2.垃圾回收机制
2.1概念
垃圾回收粗的来看有下面两种,但是我们一般说的都是对象的回收,方法的回收一般不会有什么问题。
- 对象回收
发生在堆内存空间中,也是jvm中最大的一块区域。
- 方法回收
方法的回收其实就是类卸载。类卸载的条件:
所有引用,以及对应的类加载器都为null
。要想观察类卸载的过程,可以再启动参数中加入-verbose.class
在对象的回收中主要有两个概念,那就是什么是垃圾。主要有两种方式去判断,在jvm中实现的是第二种(因为第一种可能存在循环依赖导致垃圾无法回收)
- 方式一:引用计数算法
就是对每一个创建的对象在其对象头都会有一片空间保存着一个计数器,用于记录被引用的次数,当计数器的值为 0 的时候就表示该对象可以被回收了
- 方式二:可达性分析
但是对于那些类似于连个对象相互引用的情况来说,这种引用计数的方式就没法回收他了。因此需要通过可达性分析的方式判断是否为垃圾。通过一些被称为引用链的方式向下搜索,搜索走过的路径当一个对象到 GC Roots 没有任何引用链相连时,则证明该对象是不可用的。
那些是GC Roots
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象
引用类型
- 强引用:最常见,比如new一个对象,不会回收。
- 软引用:jvm认为内存不足时会试图去回收它。(缓存场景)
- 弱引用:随时可能被回收
- 虚引用:不能通过它访问对象,供对象被finalize以后,执行指定逻辑的机制(Cleaner)
可达性级别
- 强可达:一个对象可以通过一个或多个线程可以通过各种引用访问到的情况
- 软可达:只能通过软引用才能访问
- 弱可达:只能通过弱引用才能访问
- 幻想可达:只能通过虚引用才能访问
- 不可达: 没有任何引用
2.2jvm运行时区
简图如下:
官方详细图:
方法区
JVM用来存储加载的类信息(类的全限定名,访问修饰符等),常量,静态变量,编译后的代码(class)等数据。虚拟机规范中这是一个逻辑区划。具体事项根据不同的虚拟机来实现。
如:oracle的HotSpot在java7中方法区放在永久代,java8放在元数据空间,并且通过GC机制对这个区域进行管理
堆内存
它还可以细分为 老年代,新生代,JVM启动时创建,存放对象的实例。垃圾回收器主要是管理堆内存。如果满了,就会出现OutOfMemoryError。
虚拟机栈
每个线程都在这个空间有一个私有空间。线程栈由多个栈帧组成。一个线程会执行一个或多个方法,一个方法对应一个栈帧。
栈帧内容包含:局部变量表,操作数栈,动态链接,方法返回地址,附加信息。
栈内存默认最大是1M,超出则抛出StackOverflowError
本地方法栈
和虚拟机栈功能类似,虚拟机栈是为虚拟机执行JAVA方法而准备的,本地方法栈是为虚拟机使用Native本地方法而准备的。
虚拟机规范没有规定具体的实现,由不同的虚拟机厂商去实现,HotSpot虚拟机中虚拟机栈和本地方法栈的实现方式一样,同样的,超出大小后也会抛出StackOverflowError。
程序计数器
记录当前线程执行字节码的位置,存储的是字节码指令地址,如果执行Native方法,则计数器值为空。
每个线程都在这个空间有一个私有空间,占用内存空间很少。CPU同一时间,只会执行一条线程中的指令,JVM多线程会轮流切换并分配CPU执行时间的方式。为了线程切换后,需要ton过程序计数器,来回复正确的执行位置。
2.3堆内存空间
堆内存分为新生代,老年代和永久代
jdk1.6之前:永久代,常量池在方法区
jdk1.7 :永久代,但是慢慢的退化了,去永久代,常量池在堆中
jdk1.8之后:无永久代,常量池存在元空间
内存空间大小占比
新生代:老年代 = 2:8
Eden:S0:S1 = 8:1:1
2.4垃圾收集算法
- 轻GC(普通的GC)Minor GC
一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。
- 重GC(全局GC)Full GC
**对整个堆进行整理,**包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比Minor GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:
- 1.年老代(Tenured)被写满
- 2.持久代(Perm)被写满
- 3.System.gc()被显示调用
- 4.上一次GC之后Heap的各域分配策略动态变化
垃圾清除主要有以下三种算法
标记清除法
将垃圾进行标记,然后将所有标记内容清除。两次扫描,会浪费时间,产生内存碎片;但是它不需要额外的空间
标记压缩法
在标记清除的基础上再加了一层扫描,将清楚后的内存空间进行整理,解决的就是内存碎片的问题
复制算法
主要用于年轻代,比如将S0的内容全部复制到S1,然后全部清除S0的内容
2.5垃圾收集器
- 1.Serial 串行收集器(单核,new+old)
用于单核处理器stop-the-world,单线程,停止等待垃圾回收的时间。client模式下jvm默认选项
分为新生代(复制算法)和老年代(标记整理算法)
响应时间优先
- 2.Parallel 并行收集器(new+old)
stop-the-world的停止时间依旧存在,只不过很短。server模式下jvm默认选项
分为新生代(复制算法)和老年代(标记-整理算法)
吞吐量优先,jvm默认
- 3.CMS 并发收集器(old)
用户线程一起运行去做gc,减少了停顿时间。
专用与老年代 (标记清除) 算法
响应时间优先,(新版本中被废弃,建议使用G1)
- 4.ParNew 并行收集器(new)
实际上是Serial GC的多线程版本,可控制线程数量
新生代GC实现
响应时间优先
- 5.G1 并发收集器(new/old)
g1将堆分为固定大小的区域,region之间是复制算法,但整体上实际可看做 标记-整理算法
兼顾吞吐量和响应时间
类加载器与垃圾回收机制相关推荐
- 【JVM】JVM垃圾回收机制GC
文章目录 JVM垃圾回收机制 一.堆内存区域划分 1.1内存分配策略 1.2永久代(Permanent Generation) 1.3元空间(MetaSpace) 二.标记算法 2.1引用计数算法 2 ...
- 36.JVM内存分哪几个区,每个区的作用是什么、如和判断一个对象是否存活、java垃圾回收机制、垃圾收集的方法有哪些、java类加载过程、类加载机制、双亲委派、Minor GC和Major GC
36.JVM内存分哪几个区,每个区的作用是什么? 37.如和判断一个对象是否存活?(或者GC对象的判定方法) 38.简述java垃圾回收机制? 39.java中垃圾收集的方法有哪些? 40.java类 ...
- Java垃圾回收机制与垃圾收集器
Java垃圾回收机制与垃圾收集器 前言 判定对象是否存活(标记) 引用计数法 可达性分析 算法思想 算法步骤 对象复活 引用概念的完善 垃圾回收算法 标记 - 清除法 标记 - 复制法 标记 - 整理 ...
- JVM垃圾回收机制总结(3) :按代垃圾收集器
全文转载:http://pengjiaheng.iteye.com/blog/524024 作者:和你在一起 [from JavaEye] 为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的 ...
- Java虚拟机:垃圾回收机制与垃圾收集器
一.垃圾回收机制: 1.垃圾回收的过程: JVM内存区域的程序计算器,虚拟机栈.本地方法栈的生命周期是和线程同步的,随着线程的销毁而自动释放内存,所以只有堆和方法区需要GC,方法区主要是针对常量池的回 ...
- java的垃圾回收机制包括:主流回收算法和收集器(jvm的一个主要优化方向)
2019独角兽企业重金招聘Python工程师标准>>> java的垃圾回收机制是java语言的一大特色,解放了开发人员对内存的复杂控制,但如果你想要一个高级java开发人员,还是需要 ...
- 深入理解Java虚拟机——JVM垃圾回收机制和垃圾收集器详解
一:概述 说起垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联系起来.在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,顾名思义,垃圾回收就是释 ...
- 深入浅出Java垃圾回收机制
2019独角兽企业重金招聘Python工程师标准>>> 对于Java开发人员来说,了解垃圾回收机制(GC)有哪些好处呢?首先可以满足作为一名软件工程师的求知欲,其次,深入了解GC如何 ...
- 成为JavaGC专家(1)—深入浅出Java垃圾回收机制
2019独角兽企业重金招聘Python工程师标准>>> 对于Java开发人员来说,了解垃圾回收机制(GC)有哪些好处呢?首先可以满足作为一名软件工程师的求知欲,其次,深入了解GC如何 ...
最新文章
- yum update 正在尝试其他镜像
- C#编程总结(七)数据加密——附源码
- MySQL 高级 游标介绍
- 进入法院黑名单之后,买彩票中了500万还能领奖吗?
- 拳王虚拟项目公社:低价电影票怎样赚钱,低价电影票实操赚钱方法
- c# —— 枚举和值的隐藏副作用
- Maven的安装和使用
- docker中容器与宿主机之间的网络关系
- 计算机云计算中心建设项目,某大学计算机云计算云数据中心建设方案.docx
- opencv学习笔记3:边缘检测(Canny, Sobel, Laplacian)
- java 进度条实现原理_java进度条功能的实现原理是什么?实例展示
- 施努卡:密封环ccd检测(密封圈视觉检测的原理 )
- 《线粒体疾病的遗传》学习笔记
- setcpu_SetCPU中文版
- 一款仿古文本编辑器---edit.exe
- python B站UP主所有视频封面下载
- 趣图:程序员的斗志曲线图
- javax.net.ssl.SSLPeerUnverifiedException: Hostname xxx not verified
- 做数学建模,学matlab还是python?
- IIS绑定主机屏蔽恶意解析域名的操作
热门文章
- 东软,我把青春献给了你……
- linux手写数字识别,OpenCV 3.0中的SVM训练 mnist 手写字体识别
- WindowsServer2012史记6-Windows To Go的实践
- linux下的mnt/hgfs/的共享目录无法出现的解决方案
- 强生医疗中国客户物流新仓库在苏州启用;​世茂喜达新签16家酒店项目 | 美通社头条...
- 城市云灾备,为业务连续性保驾护航
- 九、【中级篇】串口通信(USART、IIC)、读取EEPROM
- Windows 2012安全防护: 密码安全策略设置为强密码
- HTTP头信息的Content-Type
- 最后一名真正的黑客,让微软高管睡不着的人