jvm堆内存优化详解

在日常的运维工作中用到tomcat,都需要对tomcat中的jvm虚拟机进行优化,只有知道需要优化参数的具体用处,才能深刻体会优化jvm的意义所在。

在平常的工作中我们谈对jvm的优化,主要是针对java的堆内存的优化和垃圾回收机制的优化。

JVM堆内存示意图:

JVM的堆内存的组成:

young generation:新生代

eden:伊甸园区

surived:存活区

其中存活区有2个,第1个为S0,第2个为S1

old generation:老年代

permanent generation:持久代

堆内存相关参数详解:

-Xms:初始化堆内存大小,不包括持久代的内存,默认为物理内存的1/64,不会超过1G

-Xmx:最大堆内存大小,不包括持久代内存,默认为物理内存的1/4

-Xmn:新生代内存大小,默认值为Xmx的3/8,老年代内存则为5/8

-XX:NewRatio:指定新生代与老生代的内存的比值

-XX:SurvivorRatio:eden和2个存活区内存的比值,默认值为8

-XX:PermSize:初始化时持久代内存的大小

-XX:MaxPermSize:最大持久代内存的大小

建议:

1.一般建议Xms等于Xmx,好处是避免每次gc后,调整堆的大小,减少系统内存分配开销

2.建议-XX:PermSize和-XX:MaxPermSize的值相同,因为永久代大小的调整也会导致堆内存需要触发FGC; 一般设置为128M就足够;

栈内存相关参数详解:

-Xss:指定线程的最大栈空间,默认为1M

jvm垃圾收集算法:

1.引用计数算法

每个对象有一个引用计数属性,新增一个引用计数加1,引用释放时计数减1,计数为0可以回收。

此方法简单,无法解决对象相互循环引用的问题。还有一个问题是如何解决精准计数。

2.根搜索算法(GC Roots)

从GC Roots开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链时,则证明此对象是不可用的。

jvm垃圾回收算法:

1.复制算法(Copying)

2.标记清除算法(Mark-Sweep)

3.标记整理压缩算法(Mark-Compac)

复制算法:

采用从根集合扫描,并将存活对象复制到一块新的没有使用过的空间中,成本是需要一块内存交换空间

此算法用于新生代内存回收,从E区复制到S0或者S1

标记清除算法:

采用从根集合扫描,对存活的对象标记,标记完毕后再扫描整个空间中未被标记的对象,进行回收。

优点:在存活对象较多的情况下极为高效

缺点:标记清除算法直接回收不存活的对象,会造成内存碎片

标记整理压缩算法:

采用与标记清除一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象后,会将所有存活

对象往左端空闲空间移动,并更新对应的指针。此算法在标记清除的基础上,又进行了对象的移动。

优点:可以解决内存碎片问题

缺点:成本要比标记清除算法要高

垃圾回收名词解释:

1.串行回收(Serial)  --> gc单线程内存回收,会暂停所有用户线程,独占式回收

2.并行回收(Parallel)  --> 多个gc线程并行工作,会暂停所有用户线程,独占式回收

3.并发回收(CMS) --> gc线程和用户线程同时执行,不需要停顿用户线程(用户线程还是需要停顿,只是很短)

GC串行回收器(Serial回收器):

1.是一个单线程的收集器,只能使用一个CPU或一条线程去完成垃圾收集;在进行垃圾收集时,必须

暂停所有其它工作线程。直到收集完成。

2.缺点:Stop-the-World

3.优势:简单,对于单CPU的情况,由于没有多线程交互开销,反而更高效。

开启方法:

-XX:+UseSerialGC来开启

使用此参数后:新生代和老年代都采用Serial回收器进行垃圾回收

新生代使用复制算法

老年代使用标记压缩算法

GC并行回收器(ParNew回收器):

1. 并行回收也是独占式回收器,在收集过程中,应用程序会全部暂停。但由于并行回收器使用多线程

进行垃圾回收,因此在并发能力比较强的CPU上,它产生的停顿时间要短于串行回收器。而在单

CPU上或者并发能力较弱的系统中,回收效果不会比串行回收器好。

开启方法:

-XX:UserParNewGC

使用此参数后:新生代使用并行回收收集器,老年代使用串行收集器

-XX:ParallelGCThreads 可以指定线程数量,最好与CPU数量相当

新生代使用复制算法

新生代吞吐量优先回收器(Parallel Scavenge回收器):

1.吞吐量优先回收器:关注CPU吞吐量,即运行用户代码的时间/总时间,这种收集器能最高效率利用CPU。

开启方法:

-XX:UseParallelGC开启

使用此参数后:将使用Parallel Scavenge+Serial Old收集器组合回收垃圾,这也是Server模式下的默认值。

-XX:GCTimeRation 可以设置用户执行时间占总时间的比例,默认为99,即用1%时间进行垃圾收集

新生代使用复制算法

新生代吞吐量优先回收器(Parallel Scavenge回收器):老生代用Parallel Old算法

开启方法:

-XX:UseParallelOldGC开启

使用Parallel Scavenge和Parallel Old组合收集器进行收集

老年代使用标记整理算法

并发标记清除回收器(CMS回收器):

运作过程分为4个阶段:初始标记,并发标记,重新标记,并发清除

其中标记和重新标记两个阶段仍然需要Stop-The-World,其它过程中收集器和用户线程是一起工作的

启动方法:

-XX:ParallelCMSMarkSweepGC

使用此参数后:使用ParNew + CMS + Serial Old的组合进行内存回收。Serial Old作为CMS出现

“Concurrent Mode Failure”失败后的后备收集器使用。

其它参数:

-XX:ParallelCMSThreads 手工设置CMS的线程数量

-XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后发出垃圾收集,默认为68%,仅在CMS收集器时有效。

-XX:CMSFullGCBeforeCompaction:设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与-XX:CMSInitiatingOccupancyFraction一起使用

GC性能监控指标:

  吞吐量 --> 应用花在非GC上的时间百分比

CG负荷 --> 与吞吐量相反,指应用花在GC上的时间百分比

暂停时间 --> 应用花在GC stop-the-world的时间

GC频率 -->

一个交互式的应用要求暂停时间越少越好,非交互性应用,要求GC负荷越低越好

一个实时系统对暂停时间和GC负荷的要求都是越低越好

时间: 2024-10-14 09:04:10

jvm堆内存优化详解的相关文章

【转】Android开发之Bitmap的内存优化详解

本文来源:转载自: http://mobile.51cto.com/abased-410796.htm 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1.要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系

Java虚拟机(JVM)中的内存设置详解

在一些规模稍大的应用中,Java虚拟机(JVM)的内存设置尤为重要,想在项目中取得好的效率,GC(垃圾回收)的设置是第一步. PermGen space:全称是Permanent Generation space.就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域Heap space:存放Instance. GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很

JVM 与 Linux 的内存关系详解

在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用大约800m. 从表面上,物理内存应该是足够使用的:但实际运行的情况是,会发生大量使用SWAP(说明物理内存不够使用 了),如下图所示.由于SWAP和GC同时发生会致使JVM严重卡顿,所以我们要追问:内存究竟去哪儿了? 要分析这个问题,理解JVM和操作系统之间的内存关系非常重要.接下来主要就Linux与JVM之间的内存关系进行一些分析

Tomcat内存设置详解

Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存. 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置.Heap的大小是Young Generation 和Tenured Generaion 之和. 在JVM中如

Java-Tomcat内存溢出详解

Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存. 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置.Heap的大小是Young Generation 和Tenured Generaion 之和. 在JVM中如

MySQL-5.5.32 配置文件优化详解

MySQL-5.5.32 配置文件优化详解============================== [TOC] # 一.配置文件说明 > MySQL-5.5.32是Mysql5.5系列中最后一个版本,也是最后一个有配置文件的版本,为什么这么说呢,用过5.6的博友都知道,在mysql5.6中已经不提供配置文件选择,只有一个默认的配置文件,好了,我们今天说的是5.5.32这个版,就不和大家说5.6了,下面我们来具体说一下,mysql5.5.32中,提供可选的几个配置文件, * my-small.

lucene、lucene.NET详细使用与优化详解

lucene.lucene.NET详细使用与优化详解 2010-02-01 13:51:11 分类: Linux 1 lucene简介1.1 什么是luceneLucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品. 1.2 lucene能做什么要 回答这个问题,先要了解lucene的本质.实际上lucene的功能很单一,说到底,就是你给它若干个字符串,然后它为你提供一个全文搜

C语言的代码内存布局详解

一个程序本质上都是由 BSS 段.data段.text段三个组成的.这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题. BSS段:在采用段式内存管理的架构中,BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段:在采用段式内存管理的架构中,数据段(da

【转载】图说C++对象模型:对象内存布局详解

原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有所不同.文章如果有解释不清.解释不通或疏漏的地方,恳请指出. 回到顶部 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各种支持的底层