JVM常见问题(二)
6. GC收集器有哪些?它们的特点是?
1.Serial收集器(串行收集器)
2.ParNew收集器(parallel new 收集器,新生代并行收集器)
3.Parallel Scavenge收集器
4.Serial Old收集器
5.Parallel Old收集器
6.CMS收集器(Concurrent Mark Sweep,并发标记清除收集器)
- 初始标记,需要stop the world,标记GC Root能关联到的对象,速度快
- 并发标记,对GC Root执行可达性算法
- 重新标记,需要stop the world,修复并发标记时因用户线程运行而产生的标记变化,所需时间比初始标记长,但远比并发标记短
- 并发清理
- 其对于CPU资源很敏感。在并发阶段,虽然CMS收集器不会暂停用户线程,但是会因为占用了一部分CPU资源而导致应用程序变慢,总吞吐量降低。其默认启动的回收线程数是(cpu数量+3)/4,当cpu数较少的时候,会分掉大部分的cpu去执行收集器线程
- 无法处理浮动垃圾,浮动垃圾即在并发清除阶段因为是并发执行,还会产生垃圾,这一部分垃圾即为浮动垃圾,要等下次收集
- CMS收集器使用的是标记清除算法,GC后会产生碎片
7.G1收集器(Garbage First收集器)
- 使用标记整理算法,确保GC后不会产生内存碎片
- 可以精确控制停顿,允许指定消耗在垃圾回收上的时间
7. Minor GC与Full GC分别在什么时候发生?
8. 类加载的五个过程:加载、验证、准备、解析、初始化
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading)七个阶段,其中验证、准备、解析三个部分统称链接。
1.加载
- 通过一个类的权限定名来获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在java堆中生成一个代表这个类的java.lang.Class对象,作为方法去这些数据的访问入口
2.验证
- 文件格式验证:验证class文件格式规范
- 元数据验证:这个阶段是对字节码描述的信息进行语义分析,以保证起描述的信息符合java语言规范要求
- 字节码验证:进行数据流和控制流分析,这个阶段对类的方法体进行校验分析,这个阶段的任务是保证被校验类的方法在运行时不会做出危害虚拟机安全的行为
- 符号引用验证:符号引用中通过字符串描述的全限定名是否能找到对应的类、符号引用类中的类,字段和方法的访问性(private、protected、public、default)是否可被当前类访问
3.准备
4.解析
- 类或接口的解析
- 字段解析
- 类方法解析
- 接口方法解析
5.初始化
9. 双亲委派模型:Bootstrap ClassLoader、Extension ClassLoader、ApplicationClassLoader
- 启动类加载器(Bootstrap ClassLoader):是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作
- 标准扩展类加载器:是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将< Java_Runtime_Home >/lib/ext或者由系统变量 java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器
- 应用程序类加载器:由sun.misc.Launcher$AppClassLoader实现,负责加载用户类路径classpath上所指定的类库,是类加载器ClassLoader中的getSystemClassLoader()方法的返回值,开发者可以直接使用应用程序类加载器,如果程序中没有自定义过类加载器,该加载器就是程序中默认的类加载器
从JDK1.2开始,JVM规范推荐开发者使用双亲委派模式(ParentsDelegation Model)进行类加载,其加载过程如下:
- 如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器去完成
- 每一层的类加载器都把类加载请求委派给父类加载器,直到所有的类加载请求都传递给顶层的启动类加载器
- 如果顶层的启动类加载器无法完成加载请求,则子类加载器会尝试去加载,如果连最初发起类加载请求的类加载器也无法完成加载请求时,将会抛出ClassNotFoundException,而不再调用其子类加载器去进行类加载
10. 分派:静态分派与动态分派
- 静态类型:变量声明时的类型
- 实际类型:变量实例化时采用的类型
- class Car {}
- class Bus extends Car {}
- public class Main {
- public static void main(String[] args) throws Exception {
- // Car 为静态类型,Bus 为实际类型
- Car car = new Bus();
- }
- }
静态分派
- class Car {}
- class Bus extends Car {}
- class Jeep extends Car {}
- public class Main {
- public static void main(String[] args) throws Exception {
- // Car 为静态类型,Car 为实际类型
- Car car1 = new Car();
- // Car 为静态类型,Bus 为实际类型
- Car car2 = new Bus();
- // Car 为静态类型,Jeep 为实际类型
- Car car3 = new Jeep();
- showCar(car1);
- showCar(car2);
- showCar(car3);
- }
- private static void showCar(Car car) {
- System.out.println("I have a Car !");
- }
- private static void showCar(Bus bus) {
- System.out.println("I have a Bus !");
- }
- private static void showCar(Jeep jeep) {
- System.out.println("I have a Jeep !");
- }
- }
代码输出如下:
从上面的例子我们可以看出重载调用的具体方法版本是由静态类型来决定的。
动态分派
- class Car {
- public void showCar() {
- System.out.println("I have a Car !");
- }
- }
- class Bus extends Car {
- public void showCar() {
- System.out.println("I have a Bus !");
- }
- }
- class Jeep extends Car {
- public void showCar() {
- System.out.println("I have a Jeep !");
- }
- }
- public class Main {
- public static void main(String[] args) throws Exception {
- // Car 为静态类型,Car 为实际类型
- Car car1 = new Car();
- // Car 为静态类型,Bus 为实际类型
- Car car2 = new Bus();
- // Car 为静态类型,Jeep 为实际类型
- Car car3 = new Jeep();
- car1.showCar();
- car2.showCar();
- car3.showCar();
- }
- }
运行结果如下:
可以看出来重写是一个根据实际类型决定方法版本的动态分派过程。
JVM常见问题(二)的更多相关文章
- Java虚拟机详解----JVM常见问题总结
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- JVM(二)Java虚拟机组成详解
导读:详细而深入的总结,是对知识"豁然开朗"之后的"刻骨铭心",想忘记都难. Java虚拟机(Java Virtual Machine)下文简称jvm,上一篇我 ...
- JVM总括二-垃圾回收:GC Roots、回收算法、回收器
JVM总括二-垃圾回收:GC Roots.回收算法.回收器 目录:JVM总括:目录 一.判断对象是否存活 为了判断对象是否存活引入GC Roots,如果一个对象与GC Roots没有直接或间接的引用关 ...
- JVM(十二):方法调用
JVM(十二):方法调用 在 JVM(七):JVM内存结构 中,我们说到了方法执行在何种内存结构上执行:Java 方法活动在虚拟机栈中的栈帧上,栈帧的具体结构在内存结构中已经详细讲解过了,下面就让我们 ...
- 深入JVM(二)JVM概述
深入JVM(一)JVM指令手册 深入JVM(二)JVM概述 一.JVM的原理 Java虚拟机是Java平台的基石,解决了硬件和操作系统的相互独立性.不同平台(Windows,Linux和MacOS)的 ...
- JVM常见问题分析
JVM常见问题分析 启动,并且去查看日志 ./startup.sh && tail -f ../logs/catalina.out 常见有有以下几个问题: 1.java.lang.Ou ...
- JVM系列二:GC策略&内存申请、对象衰老
JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类 现在比较常用的是分代收集(generatio ...
- JVM的生命周期——JVM之二
一.首先分析两个概念 JVM实例和JVM执行引擎实例 (1)JVM实例对应了一个独立运行的java程序——进程级别 一个运行时的Java虚拟机(JVM)负责运行一个Java程序. 当启动一个Java程 ...
- jvm系列 (二) ---垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...
随机推荐
- linux——网络基础
装完linux系统要对网络(ip地址,子网掩码,网关,DNS)进行配置,才能连接网络 一,开启网卡eth0 CentOS显示没有网卡(eth0) 2.设置静态IP vim /etc/sysconfig ...
- 新概念英语(1-141)Sally's first train ride
Lesson 141 Sally's first train ride 萨莉第一交乘火车旅行 Listen to the tape then answer this question. Why was ...
- spring-oauth-server实践:使用授权方式四:client_credentials 模式下access_token做业务!!!
spring-oauth-server入门(1-10)使用授权方式四:client_credentials 模式下access_token做业务!!! 准备工作 授权方式四::客户端方式: 服务网关地 ...
- mysql(3)—— 内连接、外连接的区别
先来看一下,内连接的语法: SELECT XXX FROM XXX INNER JOIN XXX ON XXX; 这里 INNER 可以省略,在上一篇博客中我们对于笛卡尔积现象的研究中(http:/ ...
- python/*args和**kwargs
*args和**kwargs #coding=utf8 __author__ = 'Administrator' # 当函数的参数不确定时,可以使用*args和**kwargs.*args没有key值 ...
- html标记语言 --超链接
html标记语言 --超链接 四.超链接 1. 基本语法 <a href="" target="打开方式" name="页面锚点名称" ...
- MIT许可证
MIT许可证(The MIT License)是许多软件授权条款中,被广泛使用的其中一种.与其他常见的软件授权条款(如GPL.LGPL.BSD)相比,MIT是相对宽松的软件授权条款. MIT 许可证几 ...
- Downloader Middleware
downloader middleware作用:改写请求,如加入代理,加入头部等:处理异常等. # downloadMiddleware举例, 加代理 # 这里的类如果已经重新设置名称,记得在sett ...
- javascript的变量声明、数据类型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 技巧:如何提升Oracle用户密码的安全性
环境:Oracle 11.2.0.4 客户需求:主要背景是数据库中有很多业务用户名,且由于部分用户缺乏安全意识,甚至直接将自己的密码设置为和用户名一样,目前客户期望密码设置不要过于简单,最起码别和用户 ...