JVM内存管理

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

JVM内存管理mengxl2011-11-2•内存空间•内存分配•内存回收•内存分析工具主要内容•两个子系统:Classloader子系统和Executionengine(执行引擎)子系统•两个组件:Runtimedataarea(运行时数据区域)组件和Nativeinterface(本地接口)组件一、内存结构•Classloader子系统•根据给定的全限定名类名(如java.lang.Object)来装载class文件的内容到Runtimedataarea中的methodarea(方法区域)•Executionengine子系统•执行classes中的指令。任何JVMspecification实现(JDK)的核心都是Executionengine•Nativeinterface组件•与nativelibraries交互,是与其它编程语言交互的接口。当调用native方法的时候,就进入了一个全新的并且不再受虚拟机限制的世界一、内存结构•RuntimeDataArea组件——JVM的内存•Heap(堆):一个Java虚拟实例中只存在一个堆空间,用于存储对象实例及数组值,可以认为Java中所有通过new创建的对象的内存都在此分配,其大小可以通过-Xmx和-Xms来控制。一、内存结构堆被划分为新生代和旧生代,新生代又被进一步划分为Eden和Survivor区,Survivor由S0和S1组成。新建的对象都是用新生代分配内存;旧生代用于存放新生代中经过多次垃圾回收仍然存活的对象•RuntimeDataArea组件——JVM的内存•MethodArea(方法区域):被装载的class的信息存储在Methodarea的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。在SunJDK中这块区域对应PermanentSpace,又称永久代。•可能抛出异常:java.lang.OutOfMemoryError:PermGenspace一、内存结构•RuntimeDataArea组件——JVM的内存•JavaStack(java的栈):虚拟机只会直接对Javastack执行两种操作:以帧为单位的压栈或出栈,Java栈为线程私有,当方法运行完毕,对应的栈帧所占用内存自动释放。可以通过-Xss来指定大小。•可能抛出异常:StackOverflowError一、内存结构•RuntimeDataArea组件——JVM的内存•ProgramCounter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的地址。•Nativemethodstack(本地方法栈):保存native方法进入区域的地址,用于支持native方法的执行,存储了每个native方法调用的状态。当一个线程调用本地方法时,它就不再受到虚拟机关于结构和安全限制方面的约束,它既可以访问虚拟机的运行期数据区,也可以使用本地处理器以及任何类型的栈。一、内存结构•堆(Heap)和非堆(Non-heap)内存•堆内存分配•非堆内存分配•JVM内存限制(最大值)二、内存分配•堆(Heap)和非堆(Non-heap)内存•堆:就是Java代码可及的内存,是留给开发人员使用的。•非堆:就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。二、内存分配•堆内存分配•JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。•非堆内存分配•JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。二、内存分配•JVM内存限制(最大值)•首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。二、内存分配•几种经典的内存回收算法•引用计数算法•标记-清除算法(Mark-Sweep)•标记-缩并算法(Mark-Compact)•节点拷贝算法(Copying)•SunJDK的GC•新生代可用的GC——MinorGC•旧生代和持久代可用的GC•FullGC三、内存回收•引用计数算:每个对象计算指向它的指针的数量,当有一个指针指向自己时计数值加1;当删除一个指向自己的指针时,计数值减1,如果计数值减为0,说明已经不存在指向该对象的指针了,所以它可以被安全的销毁了三、内存回收——经典的内存回收算法•标记-清除算法(Mark-Sweep):整个过程分为两个阶段:标记阶段找到所有存活对象(遍历可达的对象);清除阶段清除所有垃圾对象(遍历不可达的对象)。三、内存回收——经典的内存回收算法•标记-缩并算法(Mark-Compact):为了解决内存碎片问题而产生的一种算法。它的整个过程可以描述为:标记所有的存活对象;通过重新调整存活对象位置来缩并对象图;更新指向被移动了位置的对象的指针。三、内存回收——经典的内存回收算法•节点拷贝算法(Copying):把整个堆分成两个半区(From,To),GC的过程其实就是把存活对象从一个半区From拷贝到另外一个半区To的过程,而在下一次回收时,两个半区再互换角色。在移动结束后,再更新对象的指针引用。三、内存回收——经典的内存回收算法•SunJDK的GC:SunJDK认为java程序中大部分对象的存活时间都较短,少部分对象长期存活,基于此分析,SunJDK将JVM堆划为新生代和旧生代,并根据对象存活时间提供了不同的GC实现。三、内存回收——SunJDK的GC•新生代可用的GC——MinorGC:新生代对象的特点是存活时间较短,基于节点拷贝算法实现对新生代对象的回收。在执行复制时,需要一块未使用的空间来存放存活的对象,这是新生代又被划为Eden、S0和S1的原因。EdenSpace存放新创建的对象,S0或S1的其中一块用于GC触发时作为复制的目标空间,当其中一块为复制的目标空间时,另一块中的内容则会被清空。因此通常又将S0、S1称为FromSpace和ToSpace。对新生代所占用内存进行的GC又通常被称为MinorGC。三、内存回收——SunJDK的GC•新生代可用的GC——MinorGC:三、内存回收——SunJDK的GC•旧生代和持久代可用的GC:JDK提供了串行、并行及并发三种GC来对旧生代及持久代对象所占内存进行回收•串行GC:基于Mark-Sweep-Compact实现,它结合Mark-Sweep和Mark-Compact做了些改进。•并行标记压缩GC——并行实现Mark-CompactGC•并发标记清除GC——并发实现Mark-SweepGC(CMSGC)三、内存回收——SunJDK的GC•FullGC:对新生代、旧生代、持久代都进行GC时,称为FullGC,当触发FullGC时,首先按照新生代所配置的GC方式进行GC,然后按照旧生代的GC方式对旧生代、持久代进行GC。•触发FullGC的条件:•旧生代空间不足,如果FullGC仍然空间不足,则报错:java.lang.OutOfMemoryError:Javaheapspace•PermanetGeneration空间满,如果FullGC仍然空间不足,则报错:java.lang.OutOfMemoryError:PermGenspace•CMSGC时出现promotionfailed和concurrentmodefailure,均是因为旧生代空间不足造成•统计得到的MinorGC晋升到旧生代的平均大小大于旧生代的剩余空间•存在RMI调用时,默认每小时调用一次FullGC,可以通过参数配置时间间隔•直接调用System.gc,可以DisableExplicitGC来禁止三、内存回收——SunJDK的GC•SunJDK为高效实现内存的分配及内存的回收,提供了多种GC的实现,在client和server模式下的默认选择并不相同。三、内存回收——SunJDK的GC新生代GC方式旧生代和持久代GC方式Client串行GC串行GCServer并行回收GC并行GC(JDK5.0Update6以后)新生代GC方式旧生代和持久代GC方式-XX:+UseSerialGC串行GC串行GC-XX:+UseParallelGC并行回收GC并行GC-XX:+UseConcMarkSweepGC并行GC并发GC当出现concurrentModefailure时采用串行GC-XX:+UseParNewGC并行GC串行GC-XX:+UseParallelOldGC并行回收GC并行GC-XX:+UseConcMarkSweepGC-XX:-UseParNewGC串行GC并发GC当出现ConcurrentModefailure或promotionfailed时则采用串行GC不支持的组合方式1.-XX:+UseParNewGC–XX:+UseParallelOldGC2.-XX:+UseParNewGC–XX:+UseSerialGCclient、server模式的默认GCSunJDKGC的组合方式•输出GC日志•GCPortal•JConsole•JVisualVM•JMap•JHat•JStat•EclipseMemoryAnalyzer(MAT)四、内存分析工具•输出到控制台:在JVM的启动参数中加入-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+PrintGCApplicationStoppedTime,按照参数的顺序分别输出GC的简要信息,GC的详细信息、GC的时间信息及GC造成的应用暂停的时间。•输出到指定的文件:在上面的jvm启动参数中再增加-Xloggc:gc.log可指定将gc的信息输出到gc.log中四、内存分析工具——输出GC日志•Sun提供的GCPortal用来来帮助分析GC日志,并生成相关的图形化的报表,GCPortal部署起来会有些麻烦,它需要运行在老版本的Tomcat上,同时需要数据库,部署完毕后通过上传日志文件的方式即可完成GC日志的分析,此GC日志输出的JVM参数为:-verbose:gc-XX:+PrintGCDetails-XX:+PrintGCTimeStamps[-Xloggc:文件名]四、内存分析工具——GCPortal•JConsole可以图形化查看JVM中内存的变化状况,JConsole是JDK5及以上版本中自带的工具,位于JDK的bin目录下,运行时直接运行JConsole.exe或JConsole.sh(要求支持图形界面)。JConsole中可显示JVM中很多的信息:内存、线程、类和MBean等。四、内存分析工具——JConsole•JVisualVM是JDK6update7之后推出的一个工具,它类似于JProfiler的工具,基于此工具可查看内存的消耗情况、线程的执行状况及程序中消耗CPU、内存的动作。•在内存分析上,JVisualVM的最大好处是可通过安装VisualGC插件来分析GC趋势、内存消耗详细状况。四、内存分析工具——JVisualVM•JMap是JDK中自带的一个用于分析JVM内存状况的工具,位于JDK的bin目录下。使用J

1 / 32
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功