




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第1章 JVM体系结构概述1.1 JVM简介JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM虚拟机将其内存分为程序计数器、Java栈、Java堆、方法区和本地方法栈。Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。位置:JVM运行在操作系统之上,它与硬件没有直接的交互。1.2 JVM体系结构概览JVM虚拟机将其内存分为程序计数器、Java栈、Java堆、方法区和本地方法栈。1.2.1 类装载器1. 负责加载class文件(字节码)到内存,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。2. 类加载器分为两大类:虚拟自带的加载器和用户自定义加载器。虚拟机自带的加载器又分为:(1)启动类加载器(BootStrap) C+(2)扩展类加载器(Extension)Java(3) 应用程序类加载器(AppClassLoader) Java,也叫系统类加载器,加载当前应用的classpath的所有类。用户自带的类加载器:Java.lang.ClassLoader的子类,用户可以定制类的加载方式。注:(1)JVM中的BootStrap和前端BootStrap完全是两回事。(2)图中的箭头表示继承关系。(3)sum.misc.Launcher 它是一个java虚拟的入口。3. 类装载器的双亲委派机制:某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,以此递归,如果父类加载器可以完成类加载任务,就成功返回。只有父类加载器无法完成此加载任务时,才自己去加载。这样做的好处 : 主要是为了保证java的安全特性。使用到的是沙箱机制(防止恶意代码对java的破坏,保证了java的安全和健壮性)。比如:你自己定义了一个java.lang.String,首先会加载自带的java.lang.String,而不是 你编写的1.2.2 Execution Engine执行引擎Execution Engine执行引擎负责解释命令,提交操作系统执行。1.2.3 Native Interface 本地接口本地接口的作用是融合不同的编程语言为 Java 所用,它的初衷是融合 C/C+程序,Java 诞生的时候是 C/C+横行的时候,要想立足,必须有调用 C/C+程序,于是就在内存中专门开辟了一块区域处理标记为native的代码,它的具体做法是 Native Method Stack中登记 native方法,在Execution Engine 执行时加载native libraies。目前该方法使用的越来越少了,除非是与硬件有关的应用,比如通过Java程序驱动打印机或者Java系统管理生产设备,在企业级应用中已经比较少见。因为现在的异构领域间的通信很发达,比如可以使用 Socket通信,也可以使用Web Service等等,不多做介绍。1.2.4 Native Method Stack它的具体做法是Native Method Stack中登记native方法,在Execution Engine 执行时加载本地方法库。Native 方法放在Native栈里面。1.2.5 PC寄存器每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。这块内存区域很小,它是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令。如果执行的是一个Native方法,那这个计数器是空的。1.2.6 Method Area方法区方法区不是放方法的地方方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间。 静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中静态变量+常量+类信息(构造方法/接口定义),这些属于模板信息。实例变量存在堆内存中,和方法区无关Java7以前的说法,方法区(UserService)=永久代(UserServiceImpl)1.2.7 Stack栈1.栈是什么栈也叫栈内存,主管Java程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束该栈就Over,生命周期和线程一致,是线程私有的。8种基本类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配。主要用来保存局部变量、部分结果、并参与方法的调用和返回。2.栈存储什么?栈帧中主要保存3类数据(1)本地变量(Local Variables):输入参数和输出参数以及方法内的变量;(2)栈操作(Operand Stack):记录出栈、入栈的操作;(3)栈帧数据(Frame Data):包括类文件、方法等等。3.栈运行原理栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集,当一个方法A被调用时就产生了一个栈帧 F1,并被压入到栈中,A方法又调用了 B方法,于是产生栈帧 F2 也被压入栈,B方法又调用了 C方法,于是产生栈帧 F3 也被压入栈,执行完毕后,先弹出F3栈帧,再弹出F2栈帧,再弹出F1栈帧遵循“先进后出”/“后进先出”原则。每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直至执行完毕的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。栈的大小和具体JVM的实现有关,通常在256K756K之间。图示在一个栈中有两个栈帧:栈帧 2是最先被调用的方法,先入栈,然后方法 2 又调用了方法1,栈帧 1处于栈顶的位置,栈帧 2 处于栈底,执行完毕后,依次弹出栈帧 1和栈帧 2,线程结束,栈释放。每执行一个方法都会产生一个栈帧,保存到栈(后进先出)的顶部,顶部栈就是当前的方法,该方法执行完毕 后会自动将此栈帧出栈。Exception in thread main java.lang.StackOverflowError4.栈+堆+方法区的交互关系HotSpot是使用指针的方式来访问对象:Java堆中会存放访问类元数据的地址,reference存储的就直接是对象的地址1.2.8 Runtime data area 运行数据区运行数据区是整个JVM 的重点。我们所有写的程序都被加载到这里,之后才开始运行,Java 生态系统如此的繁荣,得益于该区域的优良自治。整个JVM 框架由加载器加载文件,然后执行器在内存中处理数据,需要与异构系统交互是可以通过本地接口进行,瞧,一个完整的系统诞生了!第2章 JVM的内存管理所有的数据和程序都是在运行数据区存放,它包括以下几个部分。Stack栈:对栈来说不存在垃圾回收的问题。详情参考1.2.7节Heap堆面试靠它,调优靠它):所有的对象(包括对象变量和对象方法)、数组都是在堆中分配空间。2.1 Heap堆一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行,堆内存分为三部分:l Young Generation Space 新生区 Young/Newl Tenure generation space 养老区 Old/ Tenurel Permanent Space 永久区 Perm1、 Heap堆(Java7之前)一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行。堆内存逻辑上分为三部分:新生+养老+永久1)新生区:新生区是类的诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。新生区又分为两部分: 伊甸区(Eden space)和幸存者区(Survivor pace) ,所有的类都是在伊甸区被new出来的。幸存区有两个: 0区(Survivor 0 space)和1区(Survivor 1 space)。当伊甸园的空间用完时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。然后将伊甸园中的剩余对象移动到幸存 0区。若幸存 0区也满了,再对该区进行垃圾回收,然后移动到 1 区。那如果1 区也满了呢?再移动到养老区。若养老区也满了,那么这个时候将产生MajorGC(FullGC),进行养老区的内存清理。若养老区执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError”。如果出现java.lang.OutOfMemoryError: Java heap space异常,说明Java虚拟机的堆内存不够。原因有二:(1)Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。(2)代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)。2) 老年代:里存放的都是存活时间较久的,大小较大的对象,因此老年代使用标记整理算法。当老年代容量满的时候,会触发一次Major GC(full GC),回收新生代和老年代中不再被使用的对象资源。3)永久区(方法区)被JVM中的所有线程共享(独立于Java堆的内存空间,常驻内存区域)用于存放JDK自身所携带的 Class,Interface 的元数据,它存储的是运行环境必须的类信息,这些元信息主要包括:类的类型信息、常量池、域信息、方法信息:存放常量和类的定义信息。被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭 JVM 才会释放此区域所占用的内存。如果出现java.lang.OutOfMemoryError: PermGen space,说明是Java虚拟机对永久代Perm内存设置不够。一般出现这种情况,都是程序启动需要加载大量的第三方jar包。例如:在一个Tomcat下部署了太多的应用。或者大量动态反射生成的类不断被加载,最终导致Perm区被占满。2.2 堆参数调优1.Java7Java堆内存,逻辑上有三块:新生区、养老区、永久区,但实际上堆内存是包括新生区和养老区,如上图所示。2.Java8JDK1.8之后将最初的永久代取消了,由元空间取代。2.2.1 堆内存调优简介011)记住这个三个参数2)打印本机的最大堆内存和初始化堆内存。public static void main(String args)long maxMemory = Runtime.getRuntime().maxMemory() ;/返回 Java 虚拟机试图使用的最大内存量。long totalMemory = Runtime.getRuntime().totalMemory() ;/返回 Java 虚拟机中的内存总量。System.out.println(MAX_MEMORY = + maxMemory + (字节)、 + (maxMemory / (double)1024 / 1024) + MB);System.out.println(TOTAL_MEMORY = + totalMemory + (字节)、 + (totalMemory / (double)1024 / 1024) + MB);运行结果:2.2.2 堆内存调优简介02发现默认的情况下分配的内存是总内存的“1 / 4”、而初始化的内存为“1 / 64”VM参数 : -Xms1024m -Xmx1024m -XX:+PrintGCDetails参数解释:调整初始堆内存大小和最大堆内存大小均为1024M,并输出详细的GC处理日志。如下图:打印结果:2.2.3 堆内存调优简介031)目的:人为制造OOM2)代码:VM参数:-Xms8m -Xmx8m -XX:+PrintGCDetailsString str = ;while(true) str += str + new Random().nextInt(88888888) + new Random().nextInt(999999999) ;3)运行结果:2.2.4 Mat(Eclipse Memory Analyzer)分析dump文件,快速定位内存泄漏。获得堆中对象的统计数据获得对象相互引用的关系采用树形展现对象间相互引用的情况。支持使用OQL语言查询对象信息。第3章 JVM垃圾回收GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停(1)对新生代的对象的收集称为minor GC;(2)对旧生代的对象的收集称为Full GC;(3)程序中主动调用System.gc()强制执行的GC为Full GC。不同的对象引用类型, GC会采用不同的方法进行回收,JVM对象的引用分为了四种类型:(1)强引用:默认情况下,对象采用的均为强引用(这个对象的实例没有其他对象引用,GC时才会被回收)(2)软引用:软引用是Java中提供的一种比较适合于缓存场景的应用(只有在内存不够用的情况下才会被GC)(3)弱引用:在GC时一定会被GC回收(4)虚引用:由于虚引用只是用来得知对象是否被GC第4章 JVM相关问题1.堆和栈有什么区别?、答:(1)堆是存放对象的(包括对象变量和对象方法),但是对象内的临时变量是存在栈内存中,如例子中的methodVar是在运行期存放到栈中的。(2)栈是跟随线程的,有线程就有栈,堆是跟随JVM的,有JVM就有堆内存。2.堆内存中到底存在着什么东西?答:对象,包括对象变量以及对象方法。3.类变量和实例变量有什么区别?答:静态变量是类变量,非静态变量是实例变量,直白的说,有static修饰的变量是静态变量,没有static修饰的变量是实例变量。静态变量存在方法区中,实例变量存在堆内存中。4.Java的方法(函数)到底是传值还是传址?答:都不是,是以传值的方式传递地址,具体的说原生数据类型传递的值,引用类型传递的地址。对于原始数据类型,JVM的处理方法是从Method Area或Heap中拷贝到Stack,然后运行frame中的方法,运行完毕后再把变量指拷贝回去。 5.为什么会产生OutOfMemory产生?答:一句话:Heap内存中没有足够的可用内存了。这句话要好好理解,不是说Heap没有内存了,是说新申请内存的对象大于Heap空闲内存,比如现在Heap还空闲1M,但是新申请的内存需要1.1M,于是就会报OutOfMemory了,可能以后的对象申请的内存都只要0.9M,于是就只出现一次OutOfMemory,GC也正常了,看起来像偶发事件,就是这么回事。 但如果此时GC没有回收就会产生挂起情况,系统不响应了。 6.我产生的对象不多呀,为什么还会产生OutOfMemory?答:你继承层次忒多了,Heap中产生的对象是先产生 父类,然后才产生子类,明白不? 7.OutOfMemory错误分几种?答:分两种,分别是“OutOfMemoryError:java heap size”和”OutOfMemoryError: PermGen space”,两种都是内存溢出,heap size是说申请不到新的内存了,这个很常见,检查应用或调整堆内存大小。“PermGen space”是因为永久存储区满了,这个也很常见,一般在热发布的环境中出现,是因为每次发布应用系统都不重启,久而久之永久存储区中的死对象太多导致新对象无法申请内存,一般重新启动一下即可。8.为什么会产生StackOverflowError?答:因为一个线程把Stack内存全部耗尽了,一般是递归函数造成的。9.一个机器上可以看多个JVM吗?JVM之间可以互访吗?答:可以多个JVM,只要机器承受得了。JVM之间是不可以互访,你不能在A-JVM中访问B-JVM的Heap内存,这是不可能的。在以前老版本的JVM中,会出现A-JVM Crack后影响到B-JVM,现在版本非常少见。10.为什么Java要采用垃圾回收机制,而不采用C/C+的显式内存管理?答:为了简单,内存管理不是每个程序员都能折腾好的。11.为什么你没有详细介绍垃圾回收机制?答:垃圾回收机制每个JVM都不同,JVM Specification只是定义了要自动释放内存,也就是说它只定义了垃圾回收的抽象方法,具体怎么实现各个厂商都不同,算法各异,这东西实在没必要深入。12.JVM中到底哪些区
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 鹿邑烧烤活动方案
- 集体活动喂香蕉活动方案
- 航空物流考试题及答案
- 韩国国旗考试题及答案
- 骨科高级考试题及答案
- 幼儿园教学教案设计:报纸时装周环保材料立体裁剪
- 产品质量跟进保障承诺书9篇范文
- 企业品牌推广及形象宣传材料制作标准模板
- 服装手绘考试题及答案
- 法语口语表达与交际技巧教学教案
- 企业反恐怖安全风险评估报告
- 全国2022年10月自考05744《食品加工与保藏(专)》真题
- 电力建设土建工程施工记录填写样表
- 检修安全培训课件
- 一般毒性作用
- 操作性前提方案(OPRP)确认记录表
- GB/T 4744-2013纺织品防水性能的检测和评价静水压法
- GB 28235-2020紫外线消毒器卫生要求
- 固体废物采样记录
- 洁净手术室相关知识考核试题及答案
- Avaya新产品和解决方案介绍课件
评论
0/150
提交评论