java内存优化的一些小小理解以及设置方法

来源:互联网 发布:淘宝客怎么建个工作室 编辑:程序博客网 时间:2024/05/21 06:27

做了几年java程序的同学们都会遇到各种各样程序中出现内存溢出的情况:out of memory:java heap space,out of memory:permGen space,特别是大数据分布式的一些技术如hbase hive hadoop等,设置不对经常就会出现内存溢出。
java的垃圾回收机制虽然比较便捷傻瓜式,但真正遇到内存溢出的问题,又有很多程序员不会调试也不会合理配置jvm的内存

知其所以然要知其然。了解jvm内存机制以及垃圾回收机制后,遇到内存溢出的问题以及合理配置服务器上jvm的内存参数就会得心应手了。

1.jvm内存机制

网上有很多讲解jvm内存机制的文章,多数都是比较片面不全的,下面这个链接文章里面详细介绍了jvm内存分配的机制以及职能。
http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html

这里写图片描述

详细的内容可以看上面的这个文章,我也是从上面这个文章里面学习的。
简单的讲,jvm内存按照只能分为图中的几种

  • 程序计数器(Program Counter Register):由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。
  • 虚拟机栈(VM stacks):用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
  • 本地方法栈(native method stacks):和虚拟机栈类似,主要用于native method
  • 堆(heap):此内存区域的唯一目的就是存放对象实例。垃圾回收的主要工作空间,jvm绝大多数的内存区域都指这个地方,程序中所涉及创建的所有对象以及申请的内存空间都是这个区域,所以经常配置的参数也是针对于这个内存区。
    从垃圾回收角度来讲,这个区域又分为Eden Space(伊甸园区,新创建的对象活跃区,垃圾回收最为频繁),Survivor space(幸存区,第一轮垃圾回收没有被回收掉的对象内存区),Old space(老年区,几轮回收都没有回收走的对象存在这个内存区)
  • 方法区(non-heap):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。程序运行所需要加载的代码就会被加载到这个区域

2.垃圾回收的调试

垃圾回收的机制看了一篇理论加实践的文章http://jbutton.iteye.com/blog/1569746,学习很多。

这里只说一些实际中怎样调试jvm的垃圾回收
jdk里面有一个工具叫”jconsole”,在命令行里面输入jconsole连接到要查看的jvm进程,点击”内存”一栏。
这里写图片描述
1.右下角显示的本页面所有监控的内存区域,heap和non-heap,也是上面讲到的两个内存区域,heap是对象区垃圾回收的活跃区,non-heap是加载类字节码、常量、静态变量等。
2.heap中三个区域分别是eden space、survivor space、old space。查看每个区域的值的变化可以在设置jvm参数作为参考。
3.none-heap中两个区域分别是code cache、perm space,当运行项目需要加载很多jar包时,观察这个位置的值是否需要调整。

3.jvm参数的设置

常见的jvm内存参数设置有以下几个

  • -Xms:初始堆大小,物理内存的1/64(<1GB),默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
  • -Xmx:最大堆大小,物理内存的1/4(<1GB),默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
  • -Xmn: 年轻代大小,注意:此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
  • -XX:NewSize 设置年轻代大小(for 1.3/1.4)
  • -XX:MaxNewSize 年轻代最大值(for 1.3/1.4)
  • -XX:PermSize 设置持久代(perm gen)初始值 物理内存的1/64
  • -XX:MaxPermSize 设置持久代最大值 物理内存的1/4

根据上面监控的信息可以作为设置jvm参考。
1.out of memory:heap space,堆内存溢出,一般调大-Xms和-Xmx的值就可以
2.out of memory:permgen spcace,非堆内存溢出,一般调大-XX:PermSize和-XX:MAXPermSize的就可以
3.eden space频繁的升高降低,说明程序里面频繁创建了新的对象,频繁的gc并不是好事,因为会GC会暂停程序执行占用cpu GC,遇到这种情况就可以调大堆内存、检查修改程序或者调大-Xmn(当然不要影响old space区域的正常)
4.查看非堆部分的内存使用情况,一般服务器的内存都会很大,非堆内存的初始默认大小也会很大,可能一两个G,但实际用不了这么多,根据实际情况调整-XX:PermSize和-XX:MaxPermSize的大小。

原创粉丝点击