jvm内存调优

转载 2015年07月07日 16:05:44

1)堆

运行时数据区域,所有类实例和数组的内存均从此处分配。Java虚拟机启动时创建。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

堆由两部分组成:

其中eden+fromspace+toSpace也叫年轻代(young),old space叫旧生代。

其中还有S1,S0(在JDK的自带工具输出中会看到),分别指的是Servivor space,存放每次垃圾回收后存活的对象。

Old Generation,主要存放应用程序中生命周期长的存活对象

垃圾回收主要对Yong Generation块和Old Generation块内存进行回收,YG用来放新产生的对象,经过几次回收掉的对象往OG中移动,对YG进行垃圾回收又叫做MinorGC,对OG垃圾回收叫Major GC ,两块内存回收互不干涉。


2)非堆内存

JVM具有一个由所有线程共享的方法区。方法区属于非堆内存。它存储每个类结构,如运行时常熟池、字段和方法数据,以及方法和构造方法的代码,它是Java虚拟机启动时创建的。

除了方法区外,Java虚拟机实现科恩那个需要用于内部处理或优化的内存,这种内存也是非堆内存。例如,JIT编译器需要内存来存储从Java虚拟机代码转换来的本机代码,从而获得高性能。

Permanent Generation(图中的Permanent Space)存放JVM自己的反生对象,比如类对象和方法对象


3)回收算法阿和过程

JVM采用一种分代回收(generational Collection)的策略,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。这样就不需要每次GC都将内存中所有对象都检查一遍。

当一个URL被访问时,内存申请过程如下:

A.JVM会试图为相关的Java对象在Eden中初始化一块内存区域

B. 当Eden空间足够时,内存申请结束。否则到下一步

C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区

D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区。

E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)

F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现“Out of memory错误”


对象衰老的过程

Young generation的内存,由一块Eden和两块Survivor Space构成。新创建的对象的内存都分配自Eden。两块Survivor Space总有会一块是空闲的,用作Copying collection的目标空间。Minor collection的过程就是将Eden和在用Survivor Space中的活对象copy到空闲survivor Space中。所谓Survivor,也就是大部分对象在Eden出生之后,根本活不过GC。对象在young generation里经历了一定次数的minor Collection后,年纪大了,就会被移到old generation中,称为tenuring.(是否仅当survivor space 不足的时候才会将老对象tenuring ?目前资料没有找到描述)

剩余内存空间不足会出发GC,如Eden空间不够了就要进行minor collection,old generation空间不够要进行major collection,permanent generation空间不足会引发full GC .


4.接下来这部分讲解的是Tomcat或者其他服务器出现如下错误的分析:

1、首先是:java.lang.OutOfMemoryError:Java heap space

解释:

Heap size设置

JVM堆的设置是指Java程序运行过程中JVM可以调配使用的内存空间的设置。JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项进行设置。Heap size的大小是Yong Generation和Tenured Generation之和。

提示:在JVM中如果98%的时间是用于GC且可用的Heap Size不足2%的时候将抛出此异常信息。

提示:Heap Size最大不要超过可用物理内存的80% ,一般的要将-Xms 和-Xmx徐昂想设置为相同,而-Xmn为1/4的-Xmx值。

解决方法:

手动设置Heap Size

修改TOMCAT_HOME/bin/catalina.bat,在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: 
Java代码 
set JAVA_OPTS=%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize=256m   

set JAVA_OPTS=%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize=256m 

或修改catalina.sh 
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: 
JAVA_OPTS="$JAVA_OPTS -server -Xms800m -Xmx800m -XX:MaxNewSize=256m" 

2、其次是:java.lang.OutOfMemoryError: PermGen Space

原因:

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块区域主要是被JVM存放Class和Meta信息的,Class在被loader时就会被放到PermGen Space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很多Class的话,就很渴恩那个出现PermGen Space错误,这种错误常见在Web服务器对JSP进行Pre compile的时候,如果你的WEBApp下面都用了大量的第三方jar,其大小超过了JVM默认的大小(4M)那么就会差生此错误信息了。

解决方法: 

1. 手动设置MaxPermSize大小 
修改TOMCAT_HOME/bin/catalina.bat(Linux下为catalina.sh),在Java代码 
“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:    
set JAVA_OPTS=%JAVA_OPTS% -server -XX:PermSize=128M -XX:MaxPermSize=512m   

“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: 
set JAVA_OPTS=%JAVA_OPTS% -server -XX:PermSize=128M -XX:MaxPermSize=512m 

catalina.sh下为: 
Java代码 
JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=128M -XX:MaxPermSize=512m"  

JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=128M -XX:MaxPermSize=512m"


JVM默认的设置

堆(Heap)(News Generation 和Old Generation之和)的设置

初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G。

最大分配的内存由-Xmx指定,默认是物理内存的1/4但小于1G。

默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx

的最大限制,可以由-XX:MinHeapFreeRatio=指定。 
默认空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制,可以由-XX:MaxHeapFreeRatio=指定。

服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小,所以上面的两个参数没啥用。 

       -Xmn 设置young generation的heap大小

      -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的缺省大小和最大大小。

JVM 内存调优 与 实际案例

堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space。 Permanent 即 持久代(Permanent Generation),主...
  • jack85986370
  • jack85986370
  • 2016年10月24日 12:09
  • 2028

JVM内存模型与性能调优

Java是一门面向对象的编程语言,用对象来定义,描述和操作一切。对象数据存储在计算机内存中,Java的内存模型到底是个什么样子,让Java引为自豪的垃圾回收器又是如何工作的,如何针对JVM的内存管理进...
  • zshake
  • zshake
  • 2015年09月12日 20:39
  • 418

JVM内存模型,以及JVM性能调优

转载批注:最近因与别人讨论问题时,问到JVM内存模型,但是苦于只知道JVM的大概内容,不知道详细,也罢,近期会逐渐有充足的自己的时间,好好整理学习学习。以下内容为转载别人的资料,个人认为写的很好,就全...
  • xzknet
  • xzknet
  • 2015年03月11日 12:03
  • 3771

jvm第五节-性能调优工具使用

很多开发人员都不是很了解,jdk在安装的时候在bin目录下有很多方便我们调试的工具,有的工具是非常好用的,下面介绍一下jdk自带的调优工具和一些常见的非自带的工具:   名称      ...
  • xuehanxin
  • xuehanxin
  • 2017年04月01日 14:08
  • 1001

JVM原理讲解和调优

一、什么是JVM     JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计...
  • hjxgood
  • hjxgood
  • 2016年12月27日 15:56
  • 1955

<JVM调优>为什么内存过大?

首先推荐一本书《深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)》,应该多读几遍。 然后分享一些这段时间我查看的一些资料 : 深入理解JVM之自动内存管理   Linux...
  • OhLog
  • OhLog
  • 2017年07月15日 11:59
  • 380

Tomcat 调优及 JVM 参数优化

Tomcat 的缺省配置是不能稳定长期运行的,也就是不适合生产环境,它会死机,让你不断重新启动,甚至在午夜时分唤醒你。对于操作系统优化来说,是尽可能的增大可使用的内存容量、提高CPU 的频率,保证文件...
  • ldx891113
  • ldx891113
  • 2016年06月22日 16:20
  • 28664

jvm调优 总结 for面试

1.栈和堆 栈是运行时的单位,解决程序如何执行,代表处理逻辑 堆是存储单位,解决数据存储问题,代表数据 2. 分配内存按照8的整数倍 对象的引用: 强引用(声明对象时虚拟机生成的引用,不会被回收), ...
  • u014717807
  • u014717807
  • 2017年05月18日 17:03
  • 1141

Spark性能调优之——JVM调优之原理概述 以及降低cache操作的内存占比

性能调优分成好几块:1.常规性能调优: 分配资源,并行度。。等。2.JVM调优:JVM相关的参数。【没有大家想的那么神,虚】 通常情况下,如果你的硬件配置,基础的JVM的配置,都ok的话,J...
  • lxhandlbb
  • lxhandlbb
  • 2016年10月31日 22:28
  • 2058

JVM调优经验分享

JVM调优经验分享 前言 一、JVM调优知识背景简介 二、JVM调优参数简介 三、JVM调优目标 四、JVM调优经验 结束语...
  • u011683530
  • u011683530
  • 2016年03月30日 12:06
  • 1706
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:jvm内存调优
举报原因:
原因补充:

(最多只允许输入30个字)