古黑论
登陆 / 注册 搜索

USERCENTER

站内搜索引擎

打印 上一主题 下一主题

[Java] Java 虚拟机JVM 总结(精简版) [上]

[复制链接]
跳转到指定楼层
楼主
        学过 Java 的同学都知道,JVM 是 Java Virtual Machine(Java 虚拟机)的缩写, JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

 Java-jvm.png Java 虚拟机JVM 总结(精简版) [上]

一、线程私有

        1. 程序计数器
                当前线程所执行的字节码的行号指示器。
                对于 Java方法,记录正在执行的虚拟机字节码指令的地址;对于native方法,记录值为空(Undefined)。
                唯一一个Java 虚拟机规范中没有规定任何 OutOfMemoryError 的内存区域。
               
        2. Java 虚拟机栈
                每个线程都有独自的虚拟机栈,并且在栈中的结构是栈帧,当调用一个方法时,会为这个方法创建一个栈帧,每个方法对应的是入栈、出栈的过程。
                栈帧中包括局部变量表、操作数栈、动态链接、方法出口等信息。
                线程请求的栈深度大于虚拟机规定的栈深度,会抛出 StackOverflowError,当栈空间动态扩展,但无法申请足够的内存,将抛出 OutOfMemoryError

        3. 本地方法栈
                与虚拟机栈类似,区别在于虚拟机栈执行Java方法,本地方法栈执行 Native 方法。
               
二、线程共享

        1. 堆
                堆是垃圾回收的主要区域,很多时候被称为 GC堆。
                堆被分为新生代、老年代:Eden Space(伊甸园)、Survivor Space(幸存者区)、Tenured Gen(老年代)。
                几乎所有的对象实例及数组都在堆上分配。
                当内存空间不足时,无法完成实例分配,将抛出 OutOfMemoryError
               
        2. 方法区
                方法区在 HotSpot 中又被称为永久代。
                存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
                该区域的回收目标主要是对常量池的回收以及类的卸载。
                当内存空间不足时,无法为方法区开辟新空间时,将抛出 OutOfMemoryError
                运行时常量池,存储类加载后的常量池信息。


三、垃圾回收

                1. why - 为什么要了解垃圾回收:
                        提高系统性能,突破应用性能瓶颈。
                        排查各种内存溢出,内存泄漏的问题。
                       
                2. what1 - 哪些内存区域需要回收:
                        Java 堆和方法区。
                        Java 堆是对无用的对象的回收,方法区是对废弃的常量以及无用的类进行回收。
                       
                3. what2 - 哪些对象需要回收(对象存活判定方法):
               
                3.1 引用计数法
                        原理:给对象添加引用计数器,每当有地方引用它,引用计数器加1;引用失效,计数器减1;当计数器的值为 0,对象可被回收。
                        优点:实现简单,判定效率高。
                        缺点:存在循环引用的问题。
                               
                3.2 可达性分析法(GC Roots):
                        原理:通过一系列的称为「GC Roots」的对象作为起始点,从起始点搜索的路径称为引用链,当一个对象没有与任何引用链相连时,则证明此对象是不可用的。

                3.3 GC Roots 对象种类:
                        Java 虚拟机栈中引用的对象。
                        本地方法栈 (Native方法) 中引用的对象。
                        方法区中类静态属性引用的对象。
                        方法区中常量引用的对象。
                               
                4. when - 什么时候进行回收:
                        达到 Minor GC 或者 Full GC 的触发条件时。
                       
                        Minor GC 触发条件:
                                当新生代(Eden区)空间不足时,发起一次 Minor GC
                               
                        Full GC 触发条件:
                                调用 System.gc(),系统建议执行 Full GC,但是不必然执行.
                                当老年代空间不足时.
                                方法区空间不足时.
                                历次通过 Minor GC 后进入老年代的平均大小大于老年代的可用内存时.
                                由Eden区、From Survior区向To Survior区复制时,对象大小大于ToSurvior区可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小时。
                       
                5. how - 如何回收(垃圾回收算法):
               
                5.1 标记 - 清除算法
                       
                        原理:
                        该算法分为「标记」和「清除」两个阶段,首先标记出所有需要回收的对象,在标记完成后统一进行回收。
                       
                        特点:
                                效率:标记和清除两个阶段的效率都不高。
                                空间:标记清除之后未进行碎片整理,产生大量不连续的内存碎片,分配大对象时空间不够会经常触发垃圾回收,最终影响的仍然是效率。
                               
                5.2 标记 - 整理算法
                        原理:该算法分为「标记」和「整理」两个阶段,标记如同标记清除中的标记,整理是指不直接对标记的对象进行清理,而是让所有存活的对象移动到一边,清除掉端边界以外的内存。
                       
                        特点:
                        效率:标记和整理两个阶段的效率不高。
                        空间:优点是解决了内存碎片的问题。
                       
                5.3 复制算法(新生代采用的算法)
                       
                        原理:新生代分为 Eden、Survivor1(from)、Survivor2(to)三部分,每次使用Eden和其中一块Survivor,回收时,将存活对象复制到另一块Survivor,然后清理到刚使用的 Eden和Survivor
                       
                        特点:
                        效率:每次对整个半区进行回收,内存分配是不需要考虑内存碎片的情况;内存分配时只需要移动堆顶指针,效率高。
                        空间:未进行垃圾回收时,会有一部分空间未用上。
                       
                5.4 分代收集算法
               
                        原理: 将Java 堆分为新生代和老年代,根据各个年代的特点采用适当的收集算法。
                        特点:充分利用不同各个年代的特点采用最适当的收集算法。
                        新生代:次垃圾收集时都发现只有少量存活,选择使用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。
                        老年代:因为对象存活率高、没有额外空间进行分配担保,使用「标记-清理」或者「标记-整理」算法进行回收。

上一篇:什么样的开发方式是快速准确有效的?【下】摘要:包括从问题的思考,到开发的工具(包括编辑器) ...
下一篇:Java 虚拟机JVM 总结(精简版) [下]摘要:四、垃圾收集器 1. Serial 收集器 算法: ...
回复

使用道具 举报

沙发
屋顶,数星星 发表于 2018-7-29 21:44:57 来自手机 | 只看该作者
怀揣两块,胸怀500万!
回复 点赞 点踩

使用道具 举报

板凳
清风霁月 发表于 2018-8-1 09:45:14 | 只看该作者
看帖要回,回帖才健康,在踩踩,楼主辛苦了!
回复 点赞 点踩

使用道具 举报

地板
xinshou10086 发表于 2018-8-10 20:02:57 | 只看该作者
一年java经验,表示理解一大半,基础不太好。
回复 点赞 点踩

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

关于我们|小黑屋|手机版|Archiver|古黑论

GMT+8, 2019-5-20 20:52 , Processed in 0.216945 second(s), 48 queries .

© 2015-2019 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表