在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应用程序性能的关键环节,特别是对于那些需要处理大量数据或执行高并发操作的应用。垃圾回收(Garbage Collection, GC)的主要任务是自动管理内存,释放不再使用的对象,避免内存泄漏,...
### Java GC垃圾回收调优指南 #### 概述 在Java开发过程中,垃圾回收(Garbage Collection, GC)是管理内存资源的关键技术之一。合理的GC配置可以显著提高应用程序的性能和稳定性。本指南旨在帮助开发者深入理解...
Java内存管理是Java开发中的核心话题,特别是对于大型和高性能应用而言,良好的内存管理和垃圾回收调优至关重要。本文将深入探讨Java内存结构、垃圾回收机制以及调优策略。 首先,Java内存主要分为堆内存和非堆内存...
垃圾回收调优及JVM参数详解
Java垃圾回收机制是Java虚拟机(JVM)中至关重要的组成部分,它的主要任务是自动管理内存,回收不再使用的对象以避免内存泄漏。垃圾回收机制在Java中自动化了内存管理,使得程序员无需手动管理内存,降低了编程复杂...
Java垃圾回收器(Garbage Collector, GC)是Java编程语言中的一个重要特性,它负责自动管理内存,自动回收不再使用的对象,以防止内存泄漏。在Java中,程序员无需手动释放内存,这一过程由JVM(Java虚拟机)自动完成...
Java 14 Hotspot 虚拟机的垃圾回收调优是提升应用程序性能的关键环节。本指南主要涵盖了垃圾收集器的优化目标、策略以及各种实现,旨在帮助开发者更好地理解如何调整 JVM 参数以满足特定的需求。 优化目标与策略...
Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象...本文主要对java垃圾回收机制以及jvm参数等方面做个综述,也算是自己做开发这几年对这方面的一个总结。
本文主要围绕Tomcat中Java垃圾收集的调优进行详细讲解。 首先,JVM内存配置是性能优化的基础。`JAVA_OPTS`参数是设置JVM内存的关键,例如`JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xss512k"`。`-server`选项用于在...
以下是对Tomcat中Java垃圾收集调优的详细说明: 首先,我们需要了解JVM内存的划分。JVM根据对象的生命周期将其划分为三个主要区域: 1. **Young Generation(年轻代)**:这是对象初次被创建的地方,包括Eden区和...
Java性能调优,特别是关于垃圾回收机制的分析和指导,是优化Java应用程序的关键环节。Java的垃圾回收(Garbage Collection, GC)是自动管理内存的一种机制,它负责识别并清理那些不再使用的对象,以释放内存资源。...
- `-Xmn` 参数设置年轻代(Young Generation)的大小,年轻代是新生对象的区域,频繁进行垃圾回收。年轻代的大小会影响对象晋升到年老代的速度,从而影响垃圾收集的频率。 - `-Xss` 参数设置每个线程的堆栈大小。...
Java垃圾回收机制是Java编程中一个非常重要的概念,尤其在面试和实际开发中常常被讨论。垃圾回收(Garbage Collection, GC)是Java虚拟机自动管理内存的一种方式,旨在自动识别并释放不再使用的对象,从而避免内存...
例如,书中可能会介绍如何使用JProfiler或VisualVM等工具进行性能监控,理解JVM垃圾回收机制,以及如何调整JVM参数以优化内存使用。同时,它还会涉及SQL查询优化,如避免全表扫描,使用索引提升查询速度,以及如何...
四、垃圾回收调优 1. 设置合理的堆大小:根据应用需求调整新生代和老年代的大小,避免过早或过晚的垃圾回收。 2. 调整GC日志:通过开启GC日志,可以分析垃圾回收的性能,找出优化点。 3. 使用合适的垃圾回收器:...
Java虚拟机实战-垃圾回收及性能调优
总的来说,Java垃圾回收是JVM中不可或缺的一部分,它帮助我们解决了内存管理的复杂性,但同时也需要我们根据应用的特性和需求进行适当的调优。深入理解垃圾回收的工作机制,能够帮助我们编写出更加高效、稳定的应用...