JavaJVM相关基础知识_第1页
JavaJVM相关基础知识_第2页
JavaJVM相关基础知识_第3页
JavaJVM相关基础知识_第4页
JavaJVM相关基础知识_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JavaJVM相关基础知识jmm内存a模型)Java的并发采用共享内存模型,线程之间通过读写内存的公共状态进行通讯。多个线程之间是不能通过直接传递数据交互的,它们之间交互只能通过共享变量实现;)主要目的是定义程序中各个变量的访问规则;)Java内存模型规定所有变量都存储在主内存中,每个线程还有自己的工作内存:-线程的工作内存中保存了被该线程使用到的变量的拷贝(从主内存中拷贝过来),线程对变量的所有操作都必须在工作内存中执行,而不能直接访问主内存中的变量;不同线程之间无法直接访问对方工作内存的变量,线程间变量值的传递都要通过主内存来完成・主内存主要对应Java堆中实例数据部分;-工作内存对应于虚拟机栈中部分区域I御'之间的通信由内存模型JMMJvaI御'之间的通信由内存模型JMMJva叫存|I主)控制:-JM决定一个线程对变量的写入何时对另一个线程可见。*线程之间共享变量存储在主内存中1\;,』每个线程有4个私有的本地内存,单面存储了读写共享变量的副本。'•JMM通过控制每个线程的本地内存之间的交互,来为程序员提供内存可见性保证。)可见5性、有序性:•当一个共享变量在多个本地内存中有副本时,如果一个本地内存修改了该变量的副本,其他变量应该能够看到修改后的值,此为可见性。•保证线程的有序执行,这个为有序性。(保证线程安全)内存6间交互操作:(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态。(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。a(读取):作用于主内存变量,把主内存的一个变量读取到工作内存中。a(载入):作用于工作内存,把操作读取到工作内存的变量载入到工作内存的变量副本中(使用):作用于工作内存的变量,把工作内存中的变量值传递给一个执行引擎。a(赋值):作用于工作内存的变量。把执行引擎接收到的值赋值给工作内存的变量。(存储):把工作内存的变量的值传递给主内存(写入):把操作的值入到主内存的变量中))注)意7:*不允许a、(操作之一单独出现•不允许一个线程丢弃a操作•不允许一个线程不经过a操作,就把工作内存中的值同步到主内存中•一个新的变量只能在主内存中生成•—个变量同一时刻只允许一条线程对其进行操作。但操作可以被同一条线程执行多次,只有执行相同次数的操作,变量才会解锁-如果对一个变量进行操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行或者a操作初始化变量的值。*如果一个变量没有被锁定,不允许对其执行操作,也不允许一个被其他线程锁定的变量•对一个变量执行操作之前,需要将该变量同步回主内存中的av和栈)堆:a可动态申请的内存空间其记录空闲内存空间的链表由操作系统维护;其中的内存在不需要时可以回收,以分配给新的内存请求,其内存中的数据是无序的;—般由使用者自由分配,a分配的就是堆,需要手动释放;被所有线程共享的一块内存区域,在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例。

Si:.Heac)艸有塡眉長宇'“董爭区由赳中耳猝隔商耳哉爭飛龙4地宇轼口4也R沬海虚拟机梯+本地方^槿Si:.Heac)艸有塡眉長宇'“董爭区由赳中耳猝隔商耳哉爭飛龙4地宇轼口4也R沬海虚拟机梯+本地方^槿VNStack+(laiiveMethodStack方法国NothodArea砒计姗ProgramCounterReglster曲生代•2栈stack:先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量.;在java中,所有基本类型和引用类型都在栈中存储栈中数据的生存空间一般在当前scopes内(就是由{...}括起来的区域);先分配的内存必定后释放;—般由系统自动分配,存放函数的参数值,局部变量等,自动清除3方法区本地方法栈1)方法区MethodArea:和Java堆一样,别名叫做Non-Heap(非堆),是各个线程共享的内存区域;它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据运行时常量池RuntimeConstantPool:方法区的一部分;Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池ConstantPoolTable),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中2本地方法栈NativeMethodStacks:是为虚拟机使用到的Native方法服务注意:JVM组成本US方脱區]C挫鹉本US方脱區]4.JVM运行时数据区程序计数器是一川块内存,记录着当前程序运行到哪了字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程回复等都需要依赖这个计数器来完成;如果一个线程执行一个主要方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址如果正在执行的是一个本地方法,这个计数器的值则为空;唯个在Java的虚拟机规范中没有规定任何OutOfMemoryErro异常情况的区域其余参考2和3

堆Heap丸行弓罩运f谢散据区JT眾3議口本地方这性Native制牡血口打Scact方注区MelhodArea堆Heap丸行弓罩运f谢散据区JT眾3議口本地方这性Native制牡血口打Scact方注区MelhodArea机慌VMSuck国序计戢器CounterRegisler衣ti方注庄GCGarbageCollection:能可以自动监测对象是否超过作用域从而达到自动回收内存的目的5如何判断回收此对象1)根索算法:每个对象看做根节点,GCroots,也就是根对象,如果从一个对象没有到达根对象的路径,或者说从根对象开始无法引用到该对象,该对象就是不可达的GCRoots对象:Otject?OhjErtSGlfioabGCRoots对象:Otject?OhjErtS虚拟机栈(栈帧中的本地变量表)中引用的对象,每个方法执行的时候,jvm都会创建一个相应的栈帧(栈帧中包括操作数栈、局部变量表、运行时常量池的引用);训邸方法区中类静态属性引用的对象(使用static关键字),此类不属于任何实例;%「-耳方法区常量引用的对象(使用staticfinal关键字);本地方法栈(NativeStack)引用的对象,JNI技术使用Native方法2)引用计数法(目前未使用)java在运行时,当有一个地方引用该对象实例,会将这个对象实例加1,引用失效时就减1,jvm在扫描内存时,发现引用计数值为0的则是垃圾对象,计数值大于0的则为活跃对象Java内存泄漏实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生(OutOfMemoryErroi)常见的内存泄漏现象:1)长生命周期的对象持有短生命周期的引用,就很可能会出现内存泄露publicclassTest{Objectobject;publicvoidtest(){object=newObject();〃…其他代码}}2)静态集合类像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector等应用着

staticVectorv-newVector();for(inti=1;i<1OO;i-n-h)Objecto=newObjectf);vnadd(o);o=null;当集合里面的对象属性被修改后,再调用remove()方法时不起作用;(Connection在任何时候都无法自动回收,而Connection—旦各种连接,数据库连接,网络连接,IO连接等没有显示调用close关闭,回收,Resultset和Statement(Connection在任何时候都无法自动回收,而Connection—旦注意:尽量减少使用静态变量,类的静态变量的生命周期和类同步的;明确内存对象的有效作用域;各种连接(数据库连接,网络连接,IO连接)操作,务必显示调用close关闭;对于不需要使用的对象手动设置null值,不管GC何时会开始清理,我们都应及时的将无用的对象标记为可被清理的对象JVM垃圾回收算法Java堆中的对象是分为新生代和老年代标记-清除算法Mark-Sweep:首先标记出所有需要回收的对象,在标记完成之后统一回收所有标记的对象,但标记和清除过程的效率都不高,标记清除之后会产生大量不连续的内存碎片2)Marl3)里,I:jvm扫描所有对象,通过根搜索算法标记被引用的对象,之后会申请新的内存空间,将标记的对象复制到新的内存空间存活的对象复制完雷清空原来的内存空间,将新的内存最为vm的对象存储空间,但代价是将内存缩小为原来的一半完,jv團收算法就是分代回收2)Marl3)里,I:jvm扫描所有对象,通过根搜索算法标记被引用的对象,之后会申请新的内存空间,将标记的对象复制到新的内存空间存活的对象复制完雷清空原来的内存空间,将新的内存最为vm的对象存储空间,但代价是将内存缩小为原来的一半完,jv團收算法就是分代回收,I年轻代以复制算法为主,老年代以标记整理算法为主年轻代对象比较多|每次垃圾回收另一个内存区域,其余勺垃圾对象回收,而且要尽可能快的减少生命周期短的对象,存活的对象较少,因此只要将清除,并且复制的数量较少,效率较高;老年代是年轻代筛选出来的对象,需要删除的对象比较少,显然采用标记整理效率较高8.JVM垃圾回收器8.JVM垃圾回收器新生代收集器:Serial、ParNew、ParallelScavenge老年代收集器:CMS、SerialOld、ParallelOld整堆收集器:G1并行收集:指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态。并发收集:指用户线程与垃圾收集线程同时工作(不一定是并行的可能会交替执行)。用户程序在继续运行,而垃圾收集程序运行在另一个CPU上。吞吐量:即CPU用于运行用户代码的时间与CPU总消耗时间的比值(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))。例如:虚拟机共运行100分钟,垃圾收集器花掉1分钟,那么吞吐量就是99%1)Serial收集器串行;用于新生代的单线程收集器,采用复制算法进行垃圾收集;Serial进行垃圾收集时,不仅只用一条线程执行垃圾收集工作,它在收集的同时,所有的用户线程必须暂停StopTheWorld)适用于Client模式下的虚拟机,单CPUSerialjSerial0Id釀詞画玮謔CHJJCrtJj阴»!陳CHJJCrtJj阴»!陳ParNew收集器是一个Serial的多线程版本,其它与Serial并无区别;默认开启的收集线程数与CPU的数量相同,在CPU非常多的环境中,可以使用-XX:ParallelGCThreads参数来限制垃圾收集的线程数;存在StopTheWorld;许多运行在Server模式下的虚拟机中首选的新生代收集器,除了Serial收集器外,目前只有它能与CMS收集器配合工作F^rNew^SerialOle组合收籍运if示意MT:P湘劇i觀斷切胡oirtM函使用复制算法的收集器,又是并行的多线程收集器;使用复制算法的收集器,又是并行的多线程收集器;与ParNew的不同之处是ParNew的目标是尽可能缩短垃圾收集时用户线程的停顿时间,ParallelScavenge的目标是达到一个可控制的吞吐量;GC自适应调节:-XX:+UseAdptiveSizePolicy开启提供两个参数用于精确控制吞吐量:XX:MaxGCPauseMillis控制最大的垃圾收集停顿时间XX:GCRatio直接设置吞吐量的大小计算方法是:1/(1+n)4)SerialOldSerial的老年代版本,同样是一个单线程收集器,采用标记-整理算法;用途:在JDK1.5以及以前的版本中与ParallelScavenge收集器搭配使用;作为CMS收集器的后备方案ParallelOld

ParallelScavenge的老年代版本,是一个多线程收集器,采用标记-整理算法;JDK1.6有ParallelOld收集器可搭配ParallelScavenge收集器;JDK1.6及之后用来代替老年代的SerialOld收集器Para新生此收规則耳泳晦谄时齡潇帼匮毎记遛朗丸晡術恵户删hCPUC|用户勰6)CMS(ConcurrentMarkSweep)6)CMS(ConcurrentMarkSweep)JDK1.5推出;CMS的内存回收是与用户线程一起“并发”执行的运行过程:1)初始标记:StopTheWorld,初始标记仅仅标记GCRoots能直接关联到的对象,速度很快;2)并发标记:进行GCRootsTracing的过程,同时开启GC和用户线程,用一个闭包结构去记录可达对象找出存活对象且用户线程可并发执行;3)重新标记:修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录(采用多线程并行执行来提升效率);需要"StopTheWorld",且停顿时间比初始标记稍长,但远比并发标记短;4)并发清除:开启用户线程,同时GC线程开始对为标记的区域做清扫,回收所有的垃圾对象細no陽采馬瓏i講显注酗育用户罐餉琏行缺点:对CPU资源非常敏感;无法处理浮动垃圾,可能出现ConcurrentModelFailure失败而导致另一次FullGC的产生;因为采用标记-清除算法所以会存在空间碎片的问题,导致大对象无法分配空间,不得不提前触发一次FullGC7)G1(Garbage-First)jdk1.7才正式引用的商用收集器,在JDK1.9已经成为默认的收集器;以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征;特点:1)并行与并发:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行;2)分代收集:能独立管理整个GC堆(新生代和老年代),而不需要与其他收集器搭配;能够采用不同方式处理不同时期的对象;虽然保留分代概念,但Java堆的内存布局有很大差别;将整个堆划分为多个大小相等的独立区域(Region);新生代和老年代不再是物理隔离,它们都是一部分Region(不需要连续)的集合;3)空间整合:从整体看,是基于标记-整理算法;从局部(两个Region间)看,是基于复制算法:不会产生内存碎片,有利于长时间运行;4)可预测停顿:G1除了追求低停顿外,还能建立可预测的停顿时间模型;可以明确指定M毫秒时间片内,垃圾收集消耗的时间不超过N

毫秒有计划的避免在整个Java堆中进行全区域的垃圾收集;G1跟踪各个Region里面的垃圾堆积的大小,在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region;这样就保证了在有限的时间内可以获取尽可能高的收集效率G1如何避免整堆扫描:G1中每个Region都有一个与之对应的RememberedSet,,虚拟机发现程序在对Reference类型进行写操作时,会产生一个WriteBarrier暂时中断写操作,检查Reference引用对象是否处于多个Region中(即检查老年代中是否引用了新生代中的对象),如果是,便通过CardTable把相关引用信息记录到被引用对象所属的Region的RememberedSet中。当进行内存回收时,在GC根节点的枚举范围中加入RememberedSet即可保证不对全堆进行扫描也不会有遗漏。运行大致过程:初始标记:仅标记GCRoots能直接到的对象,并且修改TAMS(NextTopatMarkStart)的值,让下一阶段用户程序并发运行时,能在正确可用的Region中创建新对象。(需要线程停顿,但耗时很短。并发标记:从GCRoots开始对堆中对象进行可达性分析,找出存活对象。(耗时较长,但可与用户程序并发执行)最终标记:为了修正在并发标记期间因用户程序执行而导致标记产生变化的那一部分标记记录。且对象的变化记录在线程RememberedSetLogs里面,把RememberedSetLogs里面的数据合并到RememberedSet中。(需要线程停顿,但可并行执行。)筛选回收:对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。(可并发执行)9堆内存划分不同的对象,生命周期是不一样的,因此不同生命周期的对象采用不同的收集方式,可以提高垃圾回收的效率串行serial,并行parallel,以及CMS,把堆内存划分为固定大小的三个部分年轻代(younggeneration),年老代(oldgeneration),以及持久代(permanentgeneration)Sur'dvor錚厭Ed=fl1)年轻M弋Y(51ungC飞nse:ienerationPern'anent\JYoung闌毗1讪叩OldG«rwrali{)nPennanBntGenerglian分为三个区,一个Eden区,大部

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论