这里是修真院后端小课堂,每篇分享文从html
【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】java
八个方面深度解析后端知识/技能,本篇分享的是:程序员
【jvm如何运行以及内存如何分配】算法
【修真院Java小课堂】jvm如何运行以及内存如何分配后端
开场语:数组
你们好,我是IT修真院北京分院第32期的学员廖友,一枚正直纯洁善良的Java程序员,今天给你们分享一下,修真院官网Java任务拓展中的知识点——jvm如jvm
何运行以及内存如何分配工具
1、背景介绍:开发工具
jdk,jre,jvm的联系与区别优化
JDK:
是java开发工具包,是Sun公司针对java开发人员的产品,jdk中包含jre,在jdk的安装目录下有一个jre的目录,里面有两个文件夹bin和lib,在这里
能够认为bin里面就是jvm,lib中是java工做须要的类库,而java和lib合起来就称为jre
JRE:
是运行基于java语言编写的程序所不可缺乏的运行环境,也是经过它,java的开发者才能够将本身开发的程序发布到用户手中,让用户使用,与你们
熟悉的jdk不一样,jre是运行环境,并非一个开发环境,因此没有包含任何开发工具(如编译器,调试器)等,知识针对使用java程序的用户
JVM:
就是咱们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,全部的java程序首先被编译为.class文件,这种类文件能够在虚拟机上运行
,也就是说class并不直接与机器的操做系统相对应。而是通过虚拟机间接的与操做系统交互,由虚拟机将程序解释给本地系统执行,只有jvm还不能将class
执行,由于在解释class的时候jvm须要调用解释所须要的类库lib,而jre包含lib类库,jvm屏蔽了具体操做系统平台的相关信息,使得java程序只须要生成
在java虚拟机上运行的目标代码。能够在多种平台(操做系统)上不加修改的运行
JVM系统组成
类加载系统、执行引擎、运行时数据区
2、知识剖析:
一、程序计数器
程序计数器(Program Counter Register) 是一块较小的内存空间,它能够看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码
解释器工做时就是经过改变这个计数器的值来选取下一条执行字节码指令。
每条线程都有一个独立的程序计数器。
若是执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令地址。若是是native方法,计数器为空。
二、虚拟机栈
一样是线程私有,描述Java方法执行的内存模型:每一个方法在执行的同时都会建立一个栈帧(Stack Frame)用于存储局部变量表、操做数栈、动态连接、方
法出口等信息。一个方法对应一个栈帧。
局部变量表存放了各类基本类型、对象引用和returnAddress类型(指向了一条字节码指令地址)。其中64位长度long 和 double占两个局部变量空间,其余
只占一个。
规定的异常状况有两种:1.线程请求的栈的深度大于虚拟机所容许的深度,将抛出StackOverflowError异常;2.若是虚拟机能够动态扩展,若是扩展时没法
申请到足够的内存,就抛出OutOfMemoryError异常。
三、本地方法栈
和Java虚拟机栈很相似,不一样的是本地方法栈为Native方法服务。
四、Java堆
是Java虚拟机所管理的内存中最大的一块。由全部线程共享,在虚拟机启动时建立。堆区惟一目的就是存放对象实例。
堆中可细分为新生代和老年代,再细分可分为Eden空间、From Survivor空间、To Survivor空间。
堆没法扩展时,抛出OutOfMemoryError异常
五、方法区
全部线程共享,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
当方法区没法知足内存分配需求时,抛出OutOfMemoryError
六、运行时常量池
它是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项是常量池(Const Pool Table),用于存放编译期生成的各
种字面量和符号引用。并不是预置入Class文件中常量池的内容才进入方法运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用得比
较多的即是String类的intern()方法。
当方法区没法知足内存分配需求时,抛出OutOfMemoryError
七、垃圾收集(GC)
7.1 哪些内存须要回收
在运行时区域中,程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,而线程而灭;栈中的栈帧随着方法的进入和退出也有序的执行入栈出栈操做,且
栈帧的内存分配在编译期就已经肯定了。所以这几个区域的内存分配和回收都具有肯定性,在这几个区域没必要多考虑回收的问题,由于方法结束或者线程结
束时,内存天然就跟着回收了
须要进行GC操做的是方法区和堆,由于这部份内存是动态分配的,一个接口中的多个实现类须要的内存可能不同,一个方法中的多个分支须要的内存可能
也不同,咱们只有在程序处于运行期间时才能知道会建立哪些对象。
7.2 何时回收
引用计数算法:给对象中添加一个引用计数器,每当有引用它时,计数器值就加1;当引用失效时,计数器值就减1;任什么时候刻计数器为0的对象就是不可能再
被使用。
可达性分析算法:经过一系列的称为"GC Root"的对象做为起点,从这些节点开始向下搜索,搜素所走过的路径称为引用链(Reference Chain),当一个对
象到GC Root没有任何的引用链相连,就断定对象能够被回收。
7.3 如何回收
垃圾收集算法:标记-清除算法、复制算法、标记-整理算法、分代整理算法
垃圾收集器:Serial收集器、ParNew收集器、Parallel Scavenge收集器、Parallel old、Serial old、CMS、GI
八、内存分配原则
对象优先分配到Eden区
大对象直接进入老年区(须要连续内存空间的对象,例如很长的字符串以及数组)
长期存活的对象将进入老年代(对象年龄计数器,每GC一次,age+1)
动态对象年龄绑定
空间分配担保
3、编码实战
4、参考文献:
1https://www.cnblogs.com/zhouy...
[2]《深刻理解Java虚拟机》
[3]http://www.importnew.com/1551...
5、更多讨论:
Q1:有没有能够检测jvm的工具
A1:检测jvm的工具备不少,jdk本身就带有不少个,如jps,jstart,jconsloe等,这些存放在bin目录下
Q2:Java程序能够运行在不一样jvm中吗?
A2:能够的,好比安卓使用的是谷歌本身开发的davlik虚拟机,但咱们一样能够编写Java程序在上面运行
Q3:jvm优化主要指那些方面
A3:最重要的就是堆的优化,由于这是存放对象的地方,是垃圾盛产地。
6、结束语:
今天的分享就到这里啦,欢迎你们点赞、转发、留言、拍砖~