java虚拟内存

上传人:沈*** 文档编号:191474139 上传时间:2023-03-03 格式:PDF 页数:8 大小:228.99KB
收藏 版权申诉 举报 下载
java虚拟内存_第1页
第1页 / 共8页
java虚拟内存_第2页
第2页 / 共8页
java虚拟内存_第3页
第3页 / 共8页
资源描述:

《java虚拟内存》由会员分享,可在线阅读,更多相关《java虚拟内存(8页珍藏版)》请在装配图网上搜索。

1、目录java 虚拟机内存管理机制(一):JVM 内存管理总结【分享】收藏.1java 虚拟机内存管理机制(二):了解JVM的内存管理与垃圾回收收藏.5java虚拟机内存管理机制(三):我主管写的一些jvm内存管理知识收藏.8java 虚拟机内存管理机制(一):JVM 内存管理总结【分享】收藏近期看了看Java 内存泄露的一些案例,跟原来的几个哥们讨论了一下,深入研究发现JVM里面还是有不少以前不知道的细节,这里稍微剖析一下。先看一看JVM 的内部结构 如图所示,JVM 主要包括两个子系统和两个组件。两个子系统分别是Class loader子系统和 Execution engine(执行引擎)子

2、系统;两个组件分别是Runtime data area(运行时数据区域)组件和 Native interface(本地接口)组件。Class loader子系统的作用:根据给定的全限定名类名(如 java.lang.Object)来装载class 文件的内容到Runtime data area中的 method area(方法区域)。Java 程序员可以 extends java.lang.ClassLoader类来写自己的Class loader。Execution engine子系统的作用:执行classes中的指令。任何JVM specification实现(JDK)的核心都是Execu

3、tion engine,不同的JDK 例如 Sun 的 JDK 和 IBM 的 JDK 好坏主要就取决于他们各自实现的Execution engine的好坏。Native interface组件:与native libraries交互,是其它编程语言交互的接口。当调用native方法的时候,就进入了一个全新的并且不再受虚拟机限制的世界,所以也很容易出现 JVM 无法控制的native heap OutOfMemory。Runtime Data Area组件:这就是我们常说的JVM 的内存了。它主要分为五个部分1、Heap(堆):一个 Java 虚拟实例中只存在一个堆空间2、Method Are

4、a(方法区域):被装载的class 的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class 文件,然后读入这个class 文件内容并把它传输到虚拟机中。3、Java Stack(java的栈):虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈4、Program Counter(程序计数器):每一个线程都有它自己的PC 寄存器,也是该线程启动时创建的。PC 寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。5、Native method stack

5、(本地方法栈):保存 native方法进入区域的地址以上五部分只有Heap 和 Method Area是被所有线程的共享使用的;而Java stack,Program counter 和 Native method stack是以线程为粒度的,每个线程独自拥有自己的部分。了解 JVM 的系统结构,再来看看JVM 内存回收问题了Sun 的 JVM Generational Collecting(垃圾回收)原理是这样的:把对象分为年青代(Young)、年老代(Tenured)、持久代(Perm),对不同生命周期的对象使用不同的算法。(基于对对象生命周期分析)如上图所示,为Java 堆中的各代分布。

6、1.Young(年轻代)年轻代分三个区。一个Eden 区,两个Survivor区。大部分对象在Eden 区中生成。当Eden 区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制年老区(Tenured。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来

7、的对象。而且,Survivor区总有一个是空的。2.Tenured(年老代)年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。3.Perm(持久代)用于存放静态文件,如今Java 类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如 Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。举个例子:当在程序中生成对象时,正常对象会在年轻代中分配空间,如果是过大的对象也可能会直接在年老代生成(据观测在运行某程序时候每次会生成一个十兆的空间用收

8、发消息,这部分内存就会直接在年老代分配)。年轻代在空间被分配完的时候就会发起内存回收,大部分内存会被回收,一部分幸存的内存会被拷贝至Survivor的 from区,经过多次回收以后如果 from区内存也分配完毕,就会也发生内存回收然后将剩余的对象拷贝至to 区。等到 to 区也满的时候,就会再次发生内存回收然后把幸存的对象拷贝至年老区。通常我们说的JVM 内存回收总是在指堆内存回收,确实只有堆中的内容是动态申请分配的,所以以上对象的年轻代和年老代都是指的JVM 的 Heap空间,而持久代则是之前提到的Method Area,不属于 Heap。了解完这些之后,以下的转载一热衷于钻研技术的哥们Ri

9、chen Wang关于内存管理的一些建议 1、手动将生成的无用对象,中间对象置为null,加快内存回收。2、对象池技术如果生成的对象是可重用的对象,只是其中的属性不同时,可以考虑采用对象池来较少对象的生成。如果有空闲的对象就从对象池中取出使用,没有再生成新的对象,大大提高了对象的复用率。3、JVM 调优通过配置JVM 的参数来提高垃圾回收的速度,如果在没有出现内存泄露且上面两种办法都不能保证内存的回收时,可以考虑采用JVM 调优的方式来解决,不过一定要经过实体机的长期测试,因为不同的参数可能引起不同的效果。如-Xnoclassgc参数等。推荐的两款内存检测工具1、jconsole JDK自带的

10、内存监测工具,路径 jdk bin目录下 jconsole.exe,双击可运行。连接方式有两种,第一种是本地方式如调试时运行的进程可以直接连,第二种是远程方式,可以连接以服务形式启动的进程。远程连接方式是:在目标进程的jvm启动参数中添加-Dcom.sun.management.jmxremote.port=1090-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false 1090是监听的端口号具体使用时要进行修改,然后使用IP 加端口号连接即可。通过该工具可以监测到当时内

11、存的大小,CPU 的使用量以及类的加载,还提供了手动gc 的功能。优点是效率高,速度快,在不影响进行运行的情况下监测产品的运行。缺点是无法看到类或者对象之类的具体信息。使用方式很简单点击几下就可以知道功能如何了,确实有不明白之处可以上网查询文档。2、JProfiler 收费的工具,但是到处都有破解办法。安装好以后按照配置调试的方式配置好一个本地的session即可运行。可以监测当时的内存、CPU、线程等,能具体的列出内存的占用情况,还可以就某个类进行分析。优点很多,缺点太影响速度,而且有的类可能无法被织入方法,例如我使用jprofiler时一直没有备份成功过,总会有一些类的错误简单的概念:堆(

12、Heap)和非堆(Non-heap)内存按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在Java 虚拟机启动时创建的。”“在 JVM 中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM 主要管理两种类型的内存:堆和非堆。简单来说堆就是Java 代码可及的内存,是留给开发人员使用的;非堆就是JVM 留给自己用的,所以方法区、JVM 内部处理或优化所需的内存(如 JIT 编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。堆内存分配JVM 初始分配的内存由-X

13、ms指定,默认是物理内存的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内存的最大

14、值跟操作系统有很大的关系。简单的说就32 位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为 1.5G-2G,Linux系统下为2G-3G),而 64bit以上的处理器就不会有限制了java 虚拟机内存管理机制(二):了解JVM 的内存管理与垃圾回收收藏Java 语言具备GC(垃圾回收)的能力,内存管理不需要应用程序去过问,这很方便。但是,GC 是怎么进行的,JVM 的内存参数应该怎么调整,如何优化,往往我们不是太清楚。看过一些资料后,对Sun JVM的内存管理以及垃圾回收的机制大概有了一个概念,这里将这些资料归纳和翻

15、译出来。本文内容主要基于Sun JVM 1.3.1,在后续版本中有不少优化措施,但是这些基本概念还是不变的。这里假设大家对GC 的概念和基本原理都已经了解,不详细叙述了。当 JVM 进行 GC 的时候,是要消耗CPU 资源和需要一定时间的,这会影响到程序的正常运行,因此需要尽可能减少GC 消耗的时间。Java 程序运行过程中,对象的生命周期有长有短,其中相当大部分是都是比较短命的,例如局部的对象一用完就可以回收了。在大多数情况下,只要能够及时回收这些短命对象的内存,就能够确保JVM 有足够内存来分配给新的对象。因此JVM 采用一种分代回收(generational collection)的策略

16、,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。这样就不需要每次 GC 都将内存中所有对象都检查一遍。Sun JVM 1.3 有两种最基本的内存收集方式:一种称为copying或 scavenge,将所有仍然生存的对象搬到另外一块内存后,整块内存就可回收。这种方法有效率,但需要有一定的空闲内存,拷贝也有开销。这种方法用于minor collection。另外一种称为mark-compact,将活着的对象标记出来,然后搬迁

17、到一起连成大块的内存,其他内存就可以回收了。这种方法不需要占用额外的空间,但速度相对慢一些。这种方法用于major collection.在 JVM 1.3及以后的版本中,还有其他可选的内存收集方法,通过特定的参数来设定。例如:增量式回收,每次只处理一小部分;替代单线程copying的多线程并行回收;替代mark-compact的 concurrent mark-sweep回收等等。参考资料 45中有更多描述。JVM 管理的内存,通常叫做堆(heap),可以用下面的图来描述。JVM 启动后,保留一段地址空间,这个空间的大小由-Xmx指定。这块空间的大小就是heap可能的最大值,但一开始不一定全

18、都分配了物理内存,初始分配的heap 大小由-Xms 指定,如果-Xms小于-Xmx,剩余部分是virtual的,当需要的时候,再向OS 申请。而且申请之后,是继续占用而不释放给该jvm以外的程序。比如你的jvm申请了 1G 的内存,刚开始用了 200M,然后随着程序的进行,内存用到900M,然后进行垃圾回收,想释放一些内存给其他程序,这是不可以的,此时,jvm 依然会保有着900M内存。内存的监控可以查看文章运用 Jconsole监控 JVM绿色部分是young generation的内存,由一块Eden(伊甸园,有意思)和两块 Survivor Space(1.4文档中称为semi-spa

19、ce)构成。新创建的对象的内存都分配自eden。两块Survivor Space总有会一块是空闲的,用作copying collection的目标空间。Minor collection的过程就是将eden 和在用 survivor space中的活对象copy到空闲 survivor space中。所谓survivor,也就是大部分对象在伊甸园出生后,根本活不过一次GC。对象在 young generation里经历了一定次数的minor collection后,年纪大了,就会被移到 old generation中,称为tenuring。(是否仅当survivor space不足的时候才会将老

20、对象 tenuring?目前资料中没有找到描述)浅蓝色部分是old generation的内存。深蓝色部分称为permanent generation,是 JVM 用来保存 class object和 meta data,大小由-XX:PermSize 和-XX:MaxPermSize指定。大量动态生成(编译)和加载 class 会增加这部分内存的耗用。剩余内存空间不足会触发GC,如 eden 空间不够了就要进行minor collection,old generation空间不够要进行major collection,permanent generation空间不足会引发 full GC。很

21、多参数会影响里面各部分空间的分配。-XX:MinHeapFreeRatio与-XX:MaxHeapFreeRatio设定空闲内存占总内存的比例范围,这两个参数会影响GC 的频率和单次GC 的耗时。-XX:NewRatio决定 young与 old generation的比例。Young generation空间越大,minor collection频率越低,但是old generation空间小了,又可能导致 major collection频率增加。-XX:NewSize和-XX:MaxNewSize直接指定了young generation的缺省大小和最大大小。-Xmx set maxim

22、um Java heap size-Xms set initial Java heap size-XX:MinHeapFreeRatio=40 Minimum percentage of heap free after GC to avoid expansion.-XX:MaxHeapFreeRatio=70 Maximum percentage of heap free after GC to avoid shrinking.-XX:NewRatio=2 Ratio of new/old generation sizes.Sparc-client:8;x86-server:8;x86-cli

23、ent:12.-client:8(1.3.1+),x86:12-XX:NewSize=2.125m Default size of new generation(in bytes)5.0 and newer:64 bit VMs are scaled 30%larger;x86:1m;x86,5.0 and older:640k-XX:MaxNewSize=Maximum size of new generation(in bytes).Since 1.4,MaxNewSize is computed as a function of NewRatio.-XX:SurvivorRatio=25

24、 Ratio of eden/survivor space size Solaris amd64:6;Sparc in 1.3.1:25;other Solaris platforms in 5.0 and earlier:32-XX:PermSize=Initial size of permanent generation-XX:MaxPermSize=64m Size of the Permanent Generation.5.0 and newer:64 bit VMs are scaled 30%larger;1.4 amd64:96m;1.3.1-client:32m.(上面给出的缺

25、省值不一定准确,不同JVM 版本和不同OS 环境下会有不同)这里给出的只是基本的介绍,下面reference中的文章都很不错,对进一步了解或者查找性能优化参数都有帮助。java虚拟机内存管理机制(三):我主管写的一些jvm内存管理知识收藏补习了一下jvm的内存管理知识,有以下心得分享:1、jvm的内存分区分级大粒度管理相较memcache的固定单元小粒度内存管理,拥有更高的内存利用率,但带来内存碎片的问题。2、为了解决内存碎片问题,jvm采取了碎片整理的方式,但碎片整理是很耗时的。3、为了提高碎片整理的效率,因此引入了周期性的GC,而且分区分级的方式也控制了每次 GC 和碎片整理的范围。4、由于 jvm使用堆内存来存储局部变量,而局部变量具有生存周期短,先申请的后释放的特点,因此在低级别的分区中进行GC 是效率最高的方式。感觉环环相扣,有点奇妙。再补充 GC 的一个作用:寻找回路的孤立存储,并释放其占用的空间。这更要求GC 的非实时、周期性

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!