<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tim[后端技术] &#187; GC</title>
	<atom:link href="http://timyang.net/tag/gc/feed/" rel="self" type="application/rss+xml" />
	<link>http://timyang.net</link>
	<description>Tim&#039;s blog, 关于后端架构、互联网技术、分布式、大型网络应用、NoSQL、Key Value等</description>
	<lastBuildDate>Mon, 02 Aug 2010 15:34:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Java垃圾回收调优</title>
		<link>http://timyang.net/java/java_gc_tunning/</link>
		<comments>http://timyang.net/java/java_gc_tunning/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 12:04:41 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[GC]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=17</guid>
		<description><![CDATA[在Java中，通常通讯类型的服务器对GC(Garbage Collection)比较敏感。通常通讯服务器每秒需要处理大量进出的数据包，需要解析，分解成不同的业务逻辑对象并做相关的业务处理，这样会导致大量的临时对象被创建和回收。同时服务器如果需要同时保存用户状态的话，又会产生很多永久的对象，比如用户session。业务越复杂的应用往往用户session包含的引用对象就越多。这样在极端情况下会发生两件事情，long gc pause time 或 out of memory。
一，要解决long pause time首先要了解JVM中heap的结构

Java Heap为什么要分成几个不同的代(generation)? 由于80%-98%的对象的生存周期很短，大部分新对象存放在young generation可以很高效的回收，避免遍历所有对象。
young与old中内存分配的算法完全不同。young generation中由于存活的很少，要mark, sweep 然后再 compact 剩余的对象比较耗时，干脆把 live object copy 到另外一个空间更高效。old generation完全相反，里面的 live object 变化较少。因此采用 mark-sweep-compact更合适。

二，Java中四种垃圾回收算法
Java中有四种不同的回收算法，对应的启动参数为
–XX:+UseSerialGC
–XX:+UseParallelGC
–XX:+UseParallelOldGC
–XX:+UseConcMarkSweepGC
1. Serial Collector
大部分平台或者强制 java -client 默认会使用这种。
young generation算法 = serial
old generation算法 = serial (mark-sweep-compact)
这种方法的缺点很明显，stop-the-world, 速度慢。服务器应用不推荐使用。
2. Parallel Collector
在linux x64上默认是这种，其他平台要加 java -server 参数才会默认选用这种。
young = parallel，多个thread同时copy
old = mark-sweep-compact = 1
优点：新生代回收更快。因为系统大部分时间做的gc都是新生代的，这样提高了throughput(cpu用于非gc时间)
缺点：当运行在8G/16G server上old generation [...]]]></description>
			<content:encoded><![CDATA[<p>在Java中，通常通讯类型的服务器对GC(Garbage Collection)比较敏感。通常通讯服务器每秒需要处理大量进出的数据包，需要解析，分解成不同的业务逻辑对象并做相关的业务处理，这样会导致大量的临时对象被创建和回收。同时服务器如果需要同时保存用户状态的话，又会产生很多永久的对象，比如用户session。业务越复杂的应用往往用户session包含的引用对象就越多。这样在极端情况下会发生两件事情，long gc pause time 或 out of memory。</p>
<p>一，要解决long pause time首先要了解JVM中heap的结构</p>
<div id="attachment_18" class="wp-caption alignnone" style="width: 519px"><img class="size-full wp-image-18" title="java gc heap" src="http://timyang.net/blog/wp-content/uploads/2009/01/java-gc.png" alt="java gc heap" width="509" height="398" /><p class="wp-caption-text">java gc heap</p></div>
<ul>
<li>Java Heap为什么要分成几个不同的代(generation)? 由于80%-98%的对象的生存周期很短，大部分新对象存放在young generation可以很高效的回收，避免遍历所有对象。</li>
<li>young与old中内存分配的算法完全不同。young generation中由于存活的很少，要mark, sweep 然后再 compact 剩余的对象比较耗时，干脆把 live object copy 到另外一个空间更高效。old generation完全相反，里面的 live object 变化较少。因此采用 mark-sweep-compact更合适。</li>
</ul>
<p>二，Java中四种垃圾回收算法</p>
<p>Java中有四种不同的回收算法，对应的启动参数为<br />
–XX:+UseSerialGC<br />
–XX:+UseParallelGC<br />
–XX:+UseParallelOldGC<br />
–XX:+UseConcMarkSweepGC</p>
<p>1. Serial Collector<br />
大部分平台或者强制 java -client 默认会使用这种。<br />
young generation算法 = serial<br />
old generation算法 = serial (mark-sweep-compact)<br />
这种方法的缺点很明显，stop-the-world, 速度慢。服务器应用不推荐使用。</p>
<p>2. Parallel Collector<br />
在linux x64上默认是这种，其他平台要加 java -server 参数才会默认选用这种。<br />
young = parallel，多个thread同时copy<br />
old = mark-sweep-compact = 1<br />
优点：新生代回收更快。因为系统大部分时间做的gc都是新生代的，这样提高了throughput(cpu用于非gc时间)<br />
缺点：当运行在8G/16G server上old generation live object太多时候pause time过长</p>
<p>3. Parallel Compact Collector (ParallelOld)<br />
young = parallel = 2<br />
old = parallel，分成多个独立的单元，如果单元中live object少则回收，多则跳过<br />
优点：old old generation上性能较 parallel 方式有提高<br />
缺点：大部分server系统old generation内存占用会达到60%-80%, 没有那么多理想的单元live object很少方便迅速回收，同时compact方面开销比起parallel并没明显减少。</p>
<p>4. Concurent Mark-Sweep(CMS) Collector<br />
young generation = parallel collector = 2<br />
old = cms<br />
同时不做 compact 操作。<br />
优点：pause time会降低, pause敏感但CPU有空闲的场景需要建议使用策略4.<br />
缺点：cpu占用过多，cpu密集型服务器不适合。另外碎片太多，每个object的存储都要通过链表连续跳n个地方，空间浪费问题也会增大。</p>
<p>几条经验：<br />
1. java -server<br />
2. 设置Xms=Xmx=3/4物理内存<br />
3. 如果是CPU密集型服务器，使用–XX:+UseParallelOldGC, 否则–XX:+UseConcMarkSweepGC<br />
4. 新生代,Parallel/ParallelOld可设大于Xmx1/4，CMS可设小，小于Xmx1/4<br />
5. 优化程序，特别是每个用户的session中的集合类等。我们的一个模块中session中曾经为每个用户使用了一个ConcurrentHashMap, 里面通常只有几条记录，后来改成数组之后，每台机大概节约了1~2G内存。</p>
<p>不过总的说来，Java的GC算法感觉是业界最成熟的，目前很多其他语言或者框架也都支持GC了，但大多数都是只达到Java Serial gc这种层面，甚至分generation都未考虑。JDK7里面针对CMS又进行了一种改进，会采用一种G1(Garbage-First Garbage Collection)的算法。实际上<a href="http://research.sun.com/jtech/pubs/04-g1-paper-ismm.pdf" target="_blank">Garbage-First paper</a>(PDF) 2004年已经出来了，相信到JDK7已经可以用于严格生产环境，有时间也会进一步介绍一下G1。<br />
另外在今年的Sun Tech Days上<a href="http://blogs.sun.com/joeys/" target="_blank">Joey Shen</a>讲的<a href="http://download.developers.sun.com.cn/event/sun_tech_day_china/2008/20081122_beijing_day2/track1/6_TD09_JavaPerformance_JoeyS.pdf" target="_blank">Improving Java Performance</a>(PDF)也是一个很好的Java GC调优的入门教程。</p>
Similar Posts:<ul><li><a href="http://timyang.net/programming/thrift-protocol-buffers-performance-java/" rel="bookmark" title="April 2, 2009">Thrift and Protocol Buffers performance in Java</a></li>

<li><a href="http://timyang.net/programming/thrift-protocol-buffers-performance-2/" rel="bookmark" title="April 17, 2009">Thrift and Protocol Buffers performance in Java Round 2</a></li>

<li><a href="http://timyang.net/programming/thrift-protocol-buffers-java-howto/" rel="bookmark" title="April 2, 2009">Thrift, Protocol Buffers installation and Java code howto</a></li>

<li><a href="http://timyang.net/lua/lua-coroutine-vs-java-wait-notify/" rel="bookmark" title="April 27, 2009">Lua coroutine vs Java wait/notify</a></li>

<li><a href="http://timyang.net/architecture/consistent-hashing-practice/" rel="bookmark" title="September 6, 2009">某分布式应用实践一致性哈希的一些问题</a></li>
</ul><!-- Similar Posts took 9.764 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/java/java_gc_tunning/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
