在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 live object太多时候pause time过长
3. Parallel Compact Collector (ParallelOld)
young = parallel = 2
old = parallel,分成多个独立的单元,如果单元中live object少则回收,多则跳过
优点:old old generation上性能较 parallel 方式有提高
缺点:大部分server系统old generation内存占用会达到60%-80%, 没有那么多理想的单元live object很少方便迅速回收,同时compact方面开销比起parallel并没明显减少。
4. Concurent Mark-Sweep(CMS) Collector
young generation = parallel collector = 2
old = cms
同时不做 compact 操作。
优点:pause time会降低, pause敏感但CPU有空闲的场景需要建议使用策略4.
缺点:cpu占用过多,cpu密集型服务器不适合。另外碎片太多,每个object的存储都要通过链表连续跳n个地方,空间浪费问题也会增大。
几条经验:
1. java -server
2. 设置Xms=Xmx=3/4物理内存
3. 如果是CPU密集型服务器,使用–XX:+UseParallelOldGC, 否则–XX:+UseConcMarkSweepGC
4. 新生代,Parallel/ParallelOld可设大于Xmx1/4,CMS可设小,小于Xmx1/4
5. 优化程序,特别是每个用户的session中的集合类等。我们的一个模块中session中曾经为每个用户使用了一个ConcurrentHashMap, 里面通常只有几条记录,后来改成数组之后,每台机大概节约了1~2G内存。
不过总的说来,Java的GC算法感觉是业界最成熟的,目前很多其他语言或者框架也都支持GC了,但大多数都是只达到Java Serial gc这种层面,甚至分generation都未考虑。JDK7里面针对CMS又进行了一种改进,会采用一种G1(Garbage-First Garbage Collection)的算法。实际上Garbage-First paper(PDF) 2004年已经出来了,相信到JDK7已经可以用于严格生产环境,有时间也会进一步介绍一下G1。
另外在今年的Sun Tech Days上Joey Shen讲的Improving Java Performance(PDF)也是一个很好的Java GC调优的入门教程。
http://timyang.net/java/java_gc_tunning/
相关推荐
JVM内存段分配,Java垃圾回收调优,Heap设定
Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收...
Java 垃圾回收调优不同于任何其它性能优化活动。 首先你要确保自己足够了解整个应用的情况以及调优预期的结果,而不是单单满足于应用的某一部分调优。一般情况下,遵循以下过程比较容易: 明确自己的性能目标...
Java内存与垃圾回收调优,Java内存与垃圾回收的调优是一个重要的主题,特别是在高性能和大规模的应用程序中。以下是一些关键的调优建议和步骤: 理解内存结构: Java堆是主要的内存区域,用于存储对象实例。 堆内存...
垃圾回收调优及JVM参数详解
让你对java gc 的工作原理有更深的了解 谢谢下载
【译】Java 14 Hotspot 虚拟机垃圾回收调优指南(csdn)————程序
Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象...本文主要对java垃圾回收机制以及jvm参数等方面做个综述,也算是自己做开发这几年对这方面的一个总结。
关于Java垃圾回收机制的分析已经如何针对Java虚拟机来做应用程序的调优,很详细
重要性:垃圾回收是Java垃圾回收器的核心功能,对性能和内存管理至关重要。准确理解垃圾回收的原理和机制,以及能够优化和调优垃圾回收过程的能力,是一个Java开发者必备的基本技能。 面试中可能会问到的垃圾回收...
Java虚拟机实战-垃圾回收及性能调优
Java垃圾回收机制详解和调优___已看.doc
Java的垃圾回收机制详解和调优大全
gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作。
JVM的垃圾回收机制详解和调优,gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和...
java 性能调优,主要从java内存管理方面,介绍了java的内存管理,垃圾回收(GC),调优注意事项等方面系统的介绍了java的内存管理机制。
Java性能调优 6步实现项目性能全面升级+面试高频性能问题讲解视频教程分享,性能优化的N种企业级解决方案,囊括了【数据库优化】、【Tomcat优化】、【JVM优化】、【垃圾回收】、【Netty优化】、【Nginx优化】、...
JVM的堆是Java对象的活动空间,程序中的类的对象从中分配空间,其存储着正在运行着的应用程序用到的所有对象。这些对象的建立方式就是那些new一类的操作,当对象无用后,是GC来负责这个无用的对象(地球人都知道)。