JVM相关

一、JVM = 类加载器(classloader) + 执行引擎(execution engine) + 运行时数据区域(runtime data area)

二、运行时数据区

2.1 划分

程序计数器、native栈、java栈、堆区(gc区)、方法区

2.2 各区作用

2.2.1 程序计数器

线程私有

可以看作当前线程所执行字节码的信号指示器,字节码解释器会改变线程中程序计数器的值,指示代码下一步执行的字节码指令,如:分支、循环、跳转、异常处理、线程切换等。

当前线程执行Java方法时,程序计数器会记录当前程序执行的虚拟机字节码指令的地址;若执行的是native方法,程序计数器的值为空null

不会有异常

2.2.2 java栈

java栈为每个线程自身所有。

java的每个方法在执行的时候会涉及栈帧的出入栈,栈帧存储这个方法的局部变量表、操作栈、动态链接、方法返回地址等信息。

局部变量表存储了在编译期间就可知的java基本数据类型的值、对象的引用和returnAddress。

局部变量表所需要的内存空间在编译期间就分配完成,该方法需要的帧分配空间大小是确定的,在运行期间是不会改变的。

可能会有StackOverflow异常和OutofMemory异常

2.2.3 native栈

功能和Java栈类似,不同的是执行本地native方法,也是线程私有,也可能会有StackOverflow异常和OutofMemory异常

2.2.4 方法区

各线程共享区域

功能是存储已经被加载的类信息、静态变量、常量值、即时编译器编译后的代码,hotSpot说的永久区就是这块区。

gc算法是标记-清理或者标记-整理算法

可能会有OutofMemory异常

2.2.5 堆

线程共享区域

对象的产生都在这个区域,这个区域划分为eden fromsurvivor tosurvivor 三块,大小比例为8:1:1,垃圾回收操作集中在这一块区域,垃圾回收算法是复制算法。

可能会有OutofMemory异常

三、垃圾回收机制

3.1 确认哪些对象要回收

3.1.1 引用计数法

该方法的实现是给每个对象加一个引用计数器,当jvm中有地方引用该对象,那么引用计数器的值加1;当引用失效时,引用计数器的值就减1。当引用计数器的值为0,那么这个对象就是回收的对象了。

缺点:无法解决互相引用的情况。

3.1.2 可达性算法

从GcRoot对象作为起点,从这些节点向下搜索,搜索走过的路经称为引用链,当一个对象到GcRoot对象没有任何引用链时,就意味着它可以被回收了。

GcRoot对象:

虚拟机栈中引用的对象

native栈中引用的对象

方法区中常量引用对象

方法区中静态变量引用对象

3.2 怎么回收(垃圾收集算法)

3.2.1 标记-清除法

顾名思义,标记处要清除的对象,然后清除

缺点:

从效率角度来说,两个过程的执行效率都不高

从空间角度来说,会产生大量不连续的内存碎片,导致程序在运行期间需要分配大对象的时候找不到合适的内存空间而引发gc操作

3.2.2 复制法

将可用内存空间分成两块,程序运行期间,每次只使用其中一块,当发生gc操作时,将不需要清除的对象移动至另一块内存空间,然后清除当前使用的内存空间。

实际虚拟机中不是平均分成两块,而是8:1:1的比例划分。

3.2.3 标记-整理法

当发生gc操作时,将不需要清除的对象移动至内存空间的一侧,然后直接清除边界以外的内存。

3.2.4 分代收集算法

大量对象死去,少量对象存活的内存去,比如堆区,用复制算法。

对象存活率高,采用标记-清理算法或者标记-整理算法。

3.3 垃圾收集器(垃圾回收算法的实现的地方)

3.3.1 Serial

采用复制算法的单线程收集器,当该收集器进行进行垃圾回收时必须暂停其他线程的所有工作,直到它的收集工作结束。

3.3.2 ParNew

使用多线程的Serial收集器。

3.3.3 Parallel Scavenge

吞吐量优先收集器,并行的多线程收集器。关注吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾回收时间))。

3.3.4 Serial Old(MSC)

老年代的单线程收集器,利用“标记-整理算法”

3.3.5 Parallel Old

老年代中,使用多线程的的Serial Old

3.3.6 CMS

老年代的垃圾收集器。

收集过程有必要了解:

1)、初试标记,标记GCRoot能直接关联到的对象,时间很短

2)、并发标记,进行可达性分析,GCRoot Tracing过程,时间很长

3)、重新标记,修正并发标记期间,用户操作产生的,新的需要清除的对象,时间长

4)、并发清除,回收内存空间,时间长。

其中并发标记和并发清除的过程耗时很长,但是可以与用户线程并发执行。

3.3.7 G1

1)并发和并行。使用多个CPU来缩短STW时间,与用户线程并发执行

2)可预测的停顿

3)空间整合。基于标记-整理算法,无内存碎片。

四、类加载机制

4.1 过程

加载 ->验证 -> 验证->准备 ->解析 ->初始化 ->使用 ->卸载

类加载的五个过程:加载、验证、准备、解析、初始化。

加载:

      在加载阶段,虚拟机主要完成三件事:

1.通过一个类的全限定名来获取定义此类的二进制字节流。

2.将这个字节流所代表的静态存储结构转化为方法区域的运行时数据结构。

3.在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区域数据的访问入口。

验证:

      验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害。如果验证失败,就会抛出一个java.lang.VerifyError异常或其子类异常。验证过程分为四个阶段:

1.文件格式验证:验证字节流文件是否符合Class文件格式的规范,并且能被当前虚拟机正确的处理。

2.元数据验证:是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言的规范。

3.字节码验证:主要是进行数据流和控制流的分析,保证被校验类的方法在运行时不会危害虚拟机。

4.符号引用验证:符号引用验证发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在解析阶段中发生。

准备:

      准备阶段为变量分配内存并设置类变量的初始化。在这个阶段分配的仅为类的变量(static修饰的变量),而不包括类的实例变量。对已非final的变量,JVM会将其设置成“零值”,而不是其赋值语句的值:

pirvate static int size = 12;

      那么在这个阶段,size的值为0,而不是12。 final修饰的类变量将会赋值成真实的值。

解析:

      解析过程是将常量池内的符号引用替换成直接引用。主要包括四种类型引用的解析。类或接口的解析、字段解析、方法解析、接口方法解析。

初始化:

      在准备阶段,类变量已经经过一次初始化了,在这个阶段,则是根据程序员通过程序制定的计划去初始化类的变量和其他资源。这些资源有static{}块,构造函数,父类的初始化等。

      至于使用和卸载阶段阶段,这里不再过多说明,使用过程就是根据程序定义的行为执行,卸载由GC完成。

4.2 双亲委派机制

Bootstrap ClassLoader

Extention ClassLoader

Application ClassLoader

Custom ClassLoader



未完待续……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • java程序执行过程 运行时数据区域划分 线程私有区域 1. 程序计数器: 1.1. 这块内存区域很小,是当前线程...
    萍水相逢_程序员阅读 487评论 0 1
  • JVM是虚拟机,也是一种规范,他遵循着冯·诺依曼体系结构的设计原理。冯·诺依曼体系结构中,指出计算机处理的数据和指...
    Java小铺阅读 1,274评论 0 16
  • 标签: JVM 前言:JVM相关知识也是面试过程中常问的一点,学习JVM知识有助于了解Java底层实现原理,在开发...
    Vechace阅读 177评论 1 0
  • Java语言引入了Java虚拟机,具有跨平台运行的功能,能够很好地适应各种Web应用。同时,为了提高Java语言的...
    ssddd1200阅读 367评论 2 2
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,511评论 3 83