java young gcgc 需要处理吗

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&使用jstat gc命令会影响java进程吗_百度知道
使用jstat gc命令会影响java进程吗
提问者采纳
令格式jstat命令命令格式:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:old代当前新生成的容量 (字节)
PGCMN:Perm(持久代)目前已使用空间 (字节)
YGC:jstat [Options] vmid [interval] [count]参数说明:old代中初始化(最小)的大小 (字节)
OGCMX:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中Eden(伊甸园)的最大容量 (字节)
DSS:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:jstat -gc 即会每5秒一次显示进程号为12538的java进成的GC情况:年轻代中Eden(伊甸园)的容量 (字节)
EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC:perm代已使用的占当前容量百分比
S0CMX:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O,VM的进程号,单位为秒或者毫秒count: 持有次数限制
MTT :Perm(持久代)的容量 (字节)
PU:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)
TT,如果缺省则打印无数次示例说明示例通常运行命令如下:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC,暂不说明):年轻代(young)中当前的容量 (字节)
OGCMN:Old代目前已使用空间 (字节)
PC:从应用程序启动到采样时gc用的总时间(s)
NGCMN:Options:perm代中初始化(最小)的大小 (字节)
PGCMX:perm代当前新生成的容量 (字节)
S0C:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代(young)中初始化(最小)的大小 (字节)
NGCMX,显示内容如下图:结果说明显示内容说明如下(部分结果是通过其他其他参数显示的,打印次数:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时old代(全gc)gc次数
FGCT,间隔时间:old代的最大容量 (字节)
OGC:Old代的容量 (字节)
OU:perm代的最大容量 (字节)
PGC:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代(young)的最大容量 (字节)
NGC,我们一般使用 -gcutil 查看gc情况vmid:从应用程序启动到采样时年轻代中gc次数
YGCT:年轻代中第二个survivor(幸存区)的最大容量 (字节)
ECMX:old代已使用的占当前容量百分比
P,即当前运行的java进程号interval:年轻代中第一个survivor(幸存区)的最大容量 (字节)
S1CMX :年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
来自团队:
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁13532人阅读
work(13)
java(62)
本文记录GC调试的一次实验过程和结果。
GC知识要点回顾
问题1:为什么要调试GC参数?
。所以在大型系统上,调试GC是以小博大的不错选择。'small improvements in reducing
such a bottleneck can produce large gains in performance.'
问题2:怎么样调试GC?
调试GC,有:
选择合适的GC Collector整个JVM Heap堆的大小Young Generation的大小(-Xmn?m or -XX:NewRatio=?)
问题3:有哪些不同的GC Collector?
Tony Printezis (JVM大牛)在有图为证,还有一篇更早的也是有图为证
GC shortname
Generation
Command line parameter
The Copying collector
MarkSweepCompact
The Mark and Sweep Compactor
ConcurrentMarkSweep
The Concurrent Mark and Sweep Compactor
The parallel Young Generation Collector — can only be used with the Concurrent mark and sweep compactor.
PS Scavenge
The parallel object scavenger
PS MarkSweep
The parallel mark and sweep collector
简而言之,Young和Tenured各种三种Collector,分别是
Serial 单线程Parallel 多线程并行, GC线程和App线程取一运行,即GC要Stop the (app) world。Concurrent 多线程并发,GC线程和App线程可同时运行。(注: Young generation 没有CMS,取而代之的是可和CMS(Old)一起运行的ParNew)
问题4:如何选择Collector?
Serial可以直接排除掉,现在最普通的服务器也有双核64位\8G内存,默认的Collector是PS Scavenge和PS MarkSweep。所以Collector在并行(Parallel)和并发(Concurrent)两者之间选择。
问题5:选择的标准(参数指标)是什么?如何得到这些参数&#20540;(How to measure it)?
throughput和latency。从GC的耗时给出了吞吐量和响应速度的公式
Total Execution Time = Useful Time &#43; Paused Time
throughput =&Useful
Time /&Total Execution Time
= average paused time
如何得到Useful
time 和 Paused Time?即如何得到JVM的GC时间,有以下几种方式
打印GC log,java 启动参数中加入下面的语句(本文为tomcat应用)。GC Log 记录每次GC时间,可根据GC Log计算平均GC时间和累积GC时间。
CATALINA_OPTS=&$CATALINA_OPTS -verbose:gc -Xloggc:/usr/local/tomcat/gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps&
JDK自带工具,java 启动参数中加入下面的语句(本文为tomcat应用),然后在监控端可以远程连接1090端口。在内存一项,有累积GC时间和次数。注意在以min为单位显示时,只显示整数部分,如1min20s显示为1min。
CATALINA_OPTS=&$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false&
JVM监控工具,未同JDK一起发布,可在(JDK自带)中以插件的方式使用,本文为独立使用。有累积GC时间和次数,并有曲线图直观显示。
首先在Server端启动jstatd
vi jstatd.all.policy
grant codebase &file:${java.home}/../lib/tools.jar& {
permission java.security.AllP
jstatd -J-Djava.security.policy=jstatd.all.policy
然后在监控启动VisualGC,远程连接服务端进程id
visualgc 102592@remote.domain
问题5:应用请求的吞吐量和响应是否可以反映JVM的性能?
正是我们调优的目标。本文使用Jmeter来做压力测试,并给出吞吐量和响应 report。
操作系统:&
Linux 2.6.18-53.el5
体系结构:&
处理器的数目:&
分配的虚拟内存:&
2,680,408 Kb
物理内存总量:&
8,175,632 Kb
可用物理内存:&
1,140,520 Kb
交换空间总量:&
8,594,764 Kb
可用交换空间:&
8,594,680 Kb
使用用压力测试共6个client,每个client启动30个线程发送请求每个请求从16种测试样例中随机挑选一个,发送到server端测试持续10min
参数&#20540;
server使用默认GC(PS Scavenge和PS MarkSweep)server使用CMS(-XX:&#43;UseConcMarkSweepGC-XX:&#43;UseParNewGC)server使用CMS(-XX:&#43;UseConcMarkSweepGC&-XX:&#43;UseParNewGC),设置Young
generation的大小为200m(-Xmn200m)server使用CMS(-XX:&#43;UseConcMarkSweepGC&-XX:&#43;UseParNewGC),设置Young
generation的大小为600m(-Xmn600m)
观察&#20540;
Jmeter请求的summary reportserver端累积GC时间和次数
1) CMS和Parallel比较
1.1) 吞吐量和响应
Scavenge和PS MarkSweep)
(ParNew和CMS)
从Jmeter的report中可以看出, 使用CMS后吞吐量(对应总的请求数)下降18%,而最大响应时间(包括最小响应时间)有近30%的提升(变小)。这验证了Tony Printezis在Step-by-Step:Garbage Collection Tuning in the Java HotSpot(TM) Virtual
Machine中说使用CMS应用的吞吐量会相对下降,但有更好的最差响应时间。
Expect longer young GC times
Due to slower allocations into the old gen
Expect better worst-case latencies
CMS does its work mostly-concurrentlyShorter worst-case pauses
Expect lower throughput
CMS does more work
在官方的JVM性能调优中给出的建议也是,如果你的应用对峰&#20540;处理有要求,而对一两秒的停顿可以接受,则使用(-XX:&#43;UseParallelGC);如果应用对响应有更高的要求,停顿最好小于一秒,则使用(-XX:&#43;UseConcMarkSweepGC)。
1.2) GC 累积时间和次数
Scavenge和PS MarkSweep)
(ParNew和CMS)
PS累积GC时间(visualgc)为1min25s,其中Eden
189次,共52s;old 13次,共33s。
累积GC(visualgc)为2min2s,其中Eden 2333次,共1min46s;old 55次,共16s。(Jconsole和GC log却显示没有Full GC,从和中我推测visualgc与jstat显示一致,都是统计old的回收次数;而Full
GC则是Young和Old一起回收,在其他类型的GC里,Old只有Full GC时才触发)。
可以看到PS的GC频率相对低,但每次GC时间长,每次Full在3s左右徘徊,Yong在0.3s左右;CMS则是短频快,频繁快速回收,yong在0.03s(&0.1s)左右,old&0.5s。从JMeter上,使用PS
GC,Request Report会有间歇性的停顿,即server没有任何响应;CMS则相对较少,停顿不那么明显。
2) CMS下不同Xmn的比较
由于CMS Young太多频繁,又测试了分别调整Xmn为200m和600m之后的结果。200m是仿照中100m
* cpu #来设置Young gen的大小;600m则是与PS下的Young gen一致。
随着Young gen的增大(40m -& 200m -& 600m),Young 的回收次数减少,Old的回收次数增加,总体GC累积时间下降,应用吞吐量上升,最差响应时间变慢(即便和PS比较也更差,是我的测试有问题?)。
app停顿3s是不可接受的,因此倾向于使用CMS;CMS的default young gen相当小,于是设置Xmn。对于更加Prefer响应的应用,下面配置是否是黄金标配:
JVM_OPTS=&$JVM_OPTS -XX:&#43;UseParNewGC& JVM_OPTS=&$JVM_OPTS -XX:&#43;UseConcMarkSweepGC& JVM_OPTS=&$JVM_OPTS -XX:&#43;CMSParallelRemarkEnabled& JVM_OPTS=&$JVM_OPTS -XX:SurvivorRatio=8& JVM_OPTS=&$JVM_OPTS -XX:MaxTenuringThreshold=1&JVM_OPTS=&$JVM_OPTS -XX:CMSInitiatingOccupancyFraction=75&JVM_OPTS=&$JVM_OPTS -XX:&#43;UseCMSInitiatingOccupancyOnly&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:209599次
积分:3079
积分:3079
排名:第7734名
原创:96篇
转载:12篇
评论:28条
(1)(1)(1)(1)(4)(3)(4)(1)(5)(3)(2)(2)(1)(4)(9)(2)(2)(2)(5)(10)(11)(6)(6)(9)(8)(7)人气:3090753
访问用户量:3721
笔记经验:3832
总积分:261656
级别:VIP5
搜索本笔记
ta的交流分类
ta的全部笔记
浏览(9716)|(0)
&&交流分类:|笔记分类:
目录&内存管理简介 GC简介 好的Collector的特性 设计或选择Collector GC性能指标 分代GC Java Collector 快速内存分配&GC根集合 Serial Collector Parallel Collector/Throughput Collector Parallel Compacting Collector Concurrent Mark Sweep Collector (CMS) 4种Collector的对比和适用场景。 Ergonomics GC调优 OutOfMemoryError freeMemory(),totalMemory(),maxMemory() jmap工具的使用 内存管理简介&内存管理的职责为分配内存,回收内存。&没有自动内存管理的语言/平台容易发生错误。&典型的问题包括悬挂指针问题,一个指针引用了一个已经被回收的内存地址,导致程序的运行完全不可知。&另一个典型问题为内存泄露,内存已经分配,但是已经没有了指向该内存的指针,导致内存泄露。&程序员要花费大量时间在调试该类问题上。&GC简介&因此引入了Garbage Collector机制,由运行时环境来自动管理内存。&Garbage Collector解决了悬挂指针和内存泄露大部分的问题(不是全部)。&注意Garbage Collector(简称Collector)和Garbage Collection(简称GC)的区别。&Collector的职责:&分配内存。&保证有引用的内存不被释放。&回收没有指针引用的内存。&对象被引用称为活对象,对象没有被引用称为垃圾对象/垃圾/垃圾内存,找到垃圾对象并回收是Collector的一个主要工作,该过程称为GC。&Collector一般使用一个称为堆的内存池来进行内存的分配和回收。&一般的,当堆内存满或者达到一个阀值时,堆内存或者部分堆内存被GC。&好的Collector的特性&保证有引用的对象不被GC。&快速的回收内存垃圾。&在程序运行期间GC要高效,尽量少的影响程序运行。和大部分的计算机问题一样,这是一个关于空间,时间,效率平衡的问题。&避免内存碎片,内存碎片导致占用大量内存的大对象内存申请难以满足。可以采用Compaction技术避免内存碎片。Compaction技术:把活对象移向连续内存区的一端,回收其余的内存以便以后的分配。&良好的扩展性,内存分配和GC在多核机器上不应该成为性能瓶颈。&设计或选择Collector&串行或并行。&串行Collector在多核上也只有一个线程在运行,并行Collector可以同时有多个线程执行GC,但是其算法更复杂。&并发或Stop the World。&Stop the World Collection执行GC时,需要冻住所有内存,因此更简单一些,但是,在GC时,程序是被挂起的。并发GC时,程序和GC同时执行,当然,一般的并发GC算法还是需要一些Stop the World时间。&Compacting or Non-compacting or Copying&Compacting: 去除内存碎片,回收内存慢,分配内存快。&Non-compacting: 容易产生内存碎片,回收内存快,分配内存慢,对大对象内存分配支持不好。&Copying: 复制活对象到新的内存区域,原有内存直接回收,需要额外的时间来做复制,额外的空间来做存储。&GC性能指标&Throughput: 程序时间(不包含GC时间)/总时间。&GC overhead: GC时间/总时间。&Pause time: GC运行时程序挂起时间。&Frequency of GC: GC频率。&Footprint: a measure of size, such as heap size。&Promptness:对象变为垃圾到该垃圾被回收后内存可用的时间。&依赖于不同的场景,对于GC的性能指标的关注点也不一样。&分代GC&分代GC把内存划分为多个代(内存区域),每个代存储不同年龄的对象。 常见的分为2代,young和old。&分配内存时,先从young代分配,如果young代已满,可以执行GC(可能导致对象提升),如果有空间,则分配,如果young代还是没有空间,可以对整个内存堆GC。&young代GC后还存活的对象可以提升到old代。&该机制基于以下观察事实:&1 大部分新分配的对象很快就没有引用了,变成垃圾。&2 很少有old代对象引用young代对象。&基于代内存存储对象的特性,对不同代的内存可以使用不同的GC算法。&Young代GC需要高效,快速,频繁的执行,关注点主要在速度上。&Old代由于增长缓慢,因此GC不频繁,但是其内存空间比较大,因此,需要更长时间才能执行完GC。关注点在内存空间利用率上。&&Java Collector&Jvm的内存分为3代。Young, Old, Permanent。&大部分对象存储在Young代。&在Young代中经历数次GC存活的对象可以提升到Old代,大对象也可以直接分配到Old代。&Permanent代保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。&Young代由一个Eden和2个survivor组成。大部分的对象的内存分配和回收在这里完成。&Survivor存储至少经过一次GC存活下来的对象,以增大该对象在提升至old代前被回收的机会。2个survivor中有一个为空。分别为From和to survivor。&当young代内存满,执行young代GC(minor GC)。&当old或permanent代内存满,执行full GC(major GC),所有代都被GC。一般先执行young GC,再执行old, permanent GC。&有时old代太满,以至于如果young GC先运行,则无法存储提升的对象。这时,Young GC不运行,old GC算法在整个堆上运行(CMS collector是个例外,该collector不能运行在young 代上)。&&快速内存分配&大部分的内存分配请求发生时,Collector都有一块大的连续内存块,简单的内存大小计算和指针移动就可以分配内存了。因此非常快速。该技术称为bump –the-pointer技术。&对于多线程的内存分配,每个线程使用Thread Local Allocation Buffer(TLAB)进行分配,因此还是很高效。TLAB可以看作一个线程的特殊代。只有TLAB满的时候才需要进行同步操作。&GC根集合&GC运行时当前程序可以直接访问的对象。如线程中当前调用栈的方法参数,局部变量,静态变量,当前线程对象等等。&Collector根据GC根集合来寻找所有活对象。GC根集合不可达对象自然就是垃圾了。&Serial Collector&单线程,Young and old GC是串行,stop the world GC的。&Young GC。&Eden中活对象copy到to survivor中,大对象直接进old代。&From survivor中相对老的活对象进入old代,相对年轻的对象进入to survivor中。&如果to survivor放不下活对象,则这些活对象直接进入old。&经历过young GC,Eden和from survivor都变成空的内存区域,to survivor存储有活的对象。To survivor和from survivor角色互换。&Old permanent GC。&Mark-sweep-compact算法。&S1 标识哪些对象是活的对象。&S2 标识哪些对象是垃圾。&S3 把活的对象压缩到内存的一端,以便可以使用bump –the-pointer处理以后的内存分配请求。&非server-class machine 的默认GC。&也可以使用命令行参数来设定。&-XX:+UseSerialGC&Parallel Collector/Throughput Collector&利用了现代计算机大部分都是多核的事实。&Young GC。&和Serial Collector一样,是一个stop the world和copying Collector。只不过是多线程并行扫描和做copy,提高速度,减少了stop the world的时间,增大了throughput。&Old permanent GC。&和serial collector一样。Mark-sweep-compact算法。单线程。&Server-class machine的默认GC。&也可以使用命令行参数来设定。&-XX:+UseParallelGC&Parallel Compacting Collector&Young GC。&和Parallel Collector一样。&Old Permanent GC。&Stop the world,并且多线程并发GC。&每一代被划分为一些长度固定的区域。&第1步(mark phase),GC根集合划分后分发给多个GC线程,每个GC线程更新可达活对象所在区域的信息(活对象的内存位置,大小)。&第2步(summary phase),操作在区域上,而不是对象上。由于以前GC的影响,内存的一端活对象的密度比较高,在该阶段找到一个临界点,该临界点以前的区域由于活对象内存密度高,不参与GC,不做compact。该临界点之后的区域参与GC,做compact。该阶段为单线程执行。&第3步(compact phase)。GC多线程使用summary info做回收和compact工作。&可以设置GC线程数,防止GC线程长时间占有整台机器的资源。&-XX:ParallelGCThreads=n&使用命令行参数来设定。&-XX:+UseParallelOldGC&Concurrent Mark Sweep Collector (CMS)&Young GC。&和Parallel Collector一样。&Old permanent GC。&GC和程序并发执行。&Initial Phase:短暂停,标记GC根集合。单线程执行。&Concurrent marking phase: GC多线程标记从根集合可达的所有活对象。程序和GC并发运行。由于是并发运行,有可能有活对象没有被标记上。&concurrent pre-clean:单线程,并发执行。&Remark phase: 短暂停,多线程标记在Concurrent marking phase中有变化的相关对象。&Concurrent sweep phase:和程序并发执行。单线程执行。不做compacting。&concurrent reset:单线程,并发执行。&CMS不做compacting,不能使用bump-the-pointer技术,只能使用传统的内存空闲链表技术。&导致内存分配变慢,影响了Young代的GC速度,因为Young的GC如果有对象提升的话依赖于Old的内存分配。&CMS需要更多的内存空间,因为mark phase时程序还是在运行,程序可以申请更多的old空间。在mark phase中,CMS保证标识活对象,但是该过程中,活对象可能转变为垃圾,只能等待下一次GC才能回收。&和其他Collector不同,CMS不是等到old满时才GC,基于以前的统计数据(GC时间,Old空间消耗速度)来决定何时GC。CMS GC也可以基于old空间的占用率。&命令行参数:&-XX:CMSInitiatingOccupancyFraction=n,n为百分比,默认68。&可以设置&-XX:+UseCMSInitiatingOccupancyOnly 来使vm只使用old内存占用比来触发CMS GC。&Incremental Mode。&CMS的concurrent phase可以是渐进式执行。以减少程序的一次暂停时间。&命令行参数:&-XX:+UseConcMarkSweepGC&-XX:+CMSIncrementalMode&4种Collector的对比和适用场景。&直到jdk1.3.1,java只提供Serial Collector,Serial Collector在多核的机器上表现比较差。主要是throughput比较差。&大型应用(大内存,多核)应该选用并行Collector。&Serial Collector:大多数client-style机器。对于低程序暂停时间没有需求的程序。&Parallel Collector:多核机器,对于低程序暂停时间没有需求的程序。&Parallel Compacting Collector:多核机器,对于低程序暂停时间有需求的程序。&CMS Collector:和Parallel Compacting Collector相比,降低了程序暂停时间,但是young GC程序暂停时间变长,需要更大的堆空间,降低了程序的throughput。&Ergonomics&J2SE 5.0后,Collector的选择,堆大小的选择,VM(client还是server)的选择,都可以依赖平台和OS来做自动选择。&JVM会自动选择使用server mode还是client mode。但是我们一样可以手工设置。&java -server -client&Server-class machine的选择:&2个或更多的处理器 &And&2G或更多的物理内存&And&不是32bits,windows OS。&Client-class&The client JVM&The serial collector&Initial heap size = 4M&Max heap size=64M&Server-class&The server JVM&The parallel collector&Initial heap size= 1/64物理内存(&=32M),最大1G。&Max heap size=1/4物理内存,最大1G。&基于行为的调优。&可以基于最大暂停时间或throughput。&-XX:MaxGCPauseMillis=n&指示vm调整堆大小和其他参数来满足这个时间需求。如果vm不满足该目标,则减小堆大小来满足该目标。该目标没有默认值。&-XX:GCTimeRatio=n&GC time/APP time=1/(1+n)&如n=99表示GC时间占整个运行时间的1%。&如果该目标不能满足,则增大堆大小来满足该目标。默认值n=99。&Footprint Goal&如果最大暂停时间和Throughput目标都满足了,则减少堆大小直到有一个目标不满足,然后又回调。&目标优先级:&最大暂停时间&Throughput&footprint。&GC调优&由于有了Ergonomics,第一个建议就是不要手工去配置各种参数。让系统自己去根据平台和OS来选择。然后观测性能,如果OK的话,呵呵,不用搞了。&但是Ergonomics也不是万能的。因此还是需要程序员来手工搞。&注意性能问题一定要测量/调优/测量/调优不停的循环下去。&Vm mode 选择。&Java -server server mode.&Java -client client mode.&观测性能主要使用gc的统计信息。&-XX:+PrintGC 输出GC信息。&-XX:+PrintGCDetails输出GC详细信息。&-XX:+PrintGCTimeStamps 输出时间戳,和–XX:+PrintGC 或–XX:+PrintGCDetails一起使用。&-Xloggc: gc.log 输出到指定文件。&1 决定堆内存大小。&决定整个堆内存的大小。内存的大小对于Collector的性能影响是最大的。&使用以下参数来决定堆内存的大小。&可以决定堆空间的起始值和最大值,大型程序可以考虑把起始值调大,避免程序启动时频繁GC和内存扩展申请。&以及堆空间中可用内存的比例范围,vm会动态管理堆内存来满足该比例范围。&-XX:MinHeapFreeRatio=n&-XX:MaxHeapFreeRatio=n&-Xmsn Young和Old的起始内存&-Xmxn Young和Old的最大内存&2 决定代空间大小。&Young代空间越大,则minor GC的频率越小。但是,给定堆内存大小,Young代空间大,则major GC频率变大。&如果没有过多的Full GC或者过长的暂停时间问题,给young代尽量大的空间。&Young Generation Guarantee。&对于serial collector,当执行minor GC时,必须保证old代中有可用的空间来处理最坏情况(即eden和survivor空间中的对象都是活对象,需要提升至old空间),如果不满足,则该minor GC触发major GC。所以对于serial collector,设置eden+survivor的内存不要大过old代内存。&其他collector不做该保证,只有old代无法存储提升对象时才触发major GC。&对于其他collector,由于多线程做minor GC时,考虑到最坏情况,每个线程要在old代内存预留一定空间做对象提升,因此可能导致内存碎片。因此old代内存应该调整的更大一些。&-XX:NewSize=n young代空间下限。&-XX:MaxNewSize=n young代空间上限。&-XX:NewRatio=n young和old代的比例。&-XX:SurvivorRatio=n Eden和单个survivor的比例。&-XX:PermSize=n Permanent起始值。&-XX:MaxPermSize=n Permanent最大值。&3 决定使用Collector&可以考虑是否需要换一个Collector。&Collector选择&-XX:+UseSerialGC Serial&-XX:+UseParallelGC Parallel&-XX:+UseParallelOldGC Parallel compacting&-XX:+UseConcMarkSweepGC Concurrent mark–sweep (CMS)&Parallel和Parallel Compacting Collector.&-XX:ParallelGCThreads=n&-XX:MaxGCPauseMillis=n&-XX:GCTimeRatio=n&设定目标好于明确设定参数值。&为了增大Throughput,堆大小需要变大。可以把堆大小设为物理内存允许的最大值(同时程序不swapping)来检测该环境可以支持的最大throughput。&为了减小最大暂停时间和footprint,堆大小需要变小。&2个目标有一定的矛盾,因此要视具体应用场景,做平衡。&CMS Collector&-XX:+CMSIncrementalMode 和CMS同时使用。&-XX:+CMSIncrementalPacing 和CMS同时使用。&-XX:ParallelGCThreads=n&-XX:CMSInitiatingOccupancyFraction=n,n为百分比,默认68。&OutOfMemoryError&可以指定&-XX:+HeapDumpOnOutOfMemoryError&当发生OutOfMemoryError时dump出堆内存。&发生OutOfMemoryError时可以观测该Error的详细信息。&Java heap space:&调整堆大小。&程序中含有大量带有finalize方法的对象。执行finalize方法的线程顶不住了。&PermGen space:&Permanent代内存不够用了。&Requested array size exceeds VM limit。&堆内存不够用。&程序bug,一次分配太多内存。&freeMemory(),totalMemory(),maxMemory()&java.lang.Runtime类中的 freeMemory(), totalMemory(), maxMemory()这几个方法的反映的都是 java这个进程的内存情况,跟操作系统的内存根本没有关系。&maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存,以字节为单位,如果在运行java程序的时 候,没有添加-Xmx参数,那么就是jvm默认的可以使用内存大小,client为64M,server为1G。如果添加了-Xmx参数,将以这个参数后面的值为准。&totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有内存。如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,直 到挖到maxMemory()为止,所以totalMemory()是慢慢增大的。如果用了-Xms参数,程序在启动的时候就会无条件的从操作系统中挖 -Xms后面定义的内存数,然后在这些内存用的差不多的时候,再去挖。&freeMemory()是什么呢,刚才讲到如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操 作系统那里挖的,基本上是用多少挖多少,但是java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是如果你在运行java程序的时候使用了-Xms,这个时候因为程 序在启动的时候就会无条件的从操作系统中挖-Xms后面定义的内存数,这个时候,挖过来的内存可能大部分没用上,所以这个时候freeMemory()可能会有些大。&jmap工具的使用&jmap pid 查看共享对象。&jmap -heap pid 查看java进程堆的相关信息。&
java代码:
$ jmap -heap 5695
Attaching to process ID 5695, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 17.0-b16
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize
(1280.0MB)
MaxNewSize
SurvivorRatio
MaxPermSize
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity =
(127.9375MB)
25.207% used
Eden Space:
capacity =
(127.875MB)
25.368% used
From Space:
capacity = 65MB)
= 0 (0.0MB)
capacity = 65MB)
= 0 (0.0MB)
concurrent mark-sweep generation:
capacity =
(273.25MB)
(366.75MB)
42.6% used
Perm Generation:
capacity =
41.67% used
jmap –histo pid 查询各种对象占用的内存大小。&
java代码:
$ jmap -histo 5695 | less
#instances
class name
----------------------------------------------
java.util.concurrent.ConcurrentHashMap$Segment
java.util.concurrent.locks.ReentrantLock$NonfairSync
[Ljava.util.concurrent.ConcurrentHashMap$HashE
[Ljava.lang.O
&constMethodKlass&
java.lang.String
[Ljava.util.concurrent.ConcurrentHashMap$S
&methodKlass&
&symbolKlass&
java.net.SocksSocketImpl
sun.nio.ch.SocketChannelImpl
jmap –permstat pid 查看Class Loader。&jmap –dump:file=filename,format=b pid dump内存到文件。&可以使用MAT工具分析java dump文件。&
相关笔记推荐
精品视频课程推荐
本课程专注于数据结构和算法的内容,使用Java来进行代码示例,不空洞的讲解概念和理论,重点放在代码的实现和示例上。
从零开始、全面系统、成体系的讲解数据结构和基本算法,循序渐进的讲述构建软件系统所常见的数据结构和算法。
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术
技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容
数据校验、Javascript模拟多线程、下拉列表联动、操作XML、AJAX结合JSON的操作、Json-lib的使用
学习在java项目中使用log4j、jdk自带的日志框架和slf4j
深入浅出的讲解JavaBen的写法、JavaBean的用法、JavaBean的实现机制、JavaBean对应翻译的代码理解。
浏览(9716)|(0)
&&交流分类:|笔记分类:
版权所有 Copyright(C) 私塾在线学习网

我要回帖

更多关于 java young gc 的文章

 

随机推荐