在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调优的入门教程。
Heap设定与垃圾回收
-Xms
|
初始Heap大小
|
-Xmx
|
java heap最大值
|
-Xmn
|
young generation的heap大小
|
-Xss
|
每个线程的
Stack
大小
|
相关推荐
JVM内存管理是优化Java应用性能的关键环节,涉及到内存分配、垃圾回收以及内存溢出等问题。毕玄,一位在淘宝有着丰富经验的专家,通过他的演讲PPT,我们能深入理解JVM内存的实现、使用和调优。 ### 一、JVM内存实现...
《JVM性能调优——JVM内存整理及GC回收》是针对Java开发人员的重要主题,尤其是在大型企业级应用中,确保JVM(Java虚拟机)的高效运行是至关重要的。本资料深入探讨了如何通过调整JVM内存设置和优化垃圾回收机制来...
- **GC频率**:过高可能意味着内存分配不合理或存在内存泄漏。 - **暂停时间(Pause Time)**:长时间的GC暂停会影响用户体验,应尽可能降低。 - **吞吐量(Throughput)**:应用运行时间占总时间的比例,调优的目标...
调整JVM参数可以控制内存分配、垃圾回收策略、并行度等,例如 `-Xms` 和 `-Xmx` 设定堆内存大小,`-XX:NewRatio` 控制年轻代和老年代的比例,`-XX:+UseConcMarkSweepGC` 开启CMS垃圾回收器等。通过监控工具(如...
JVM垃圾回收调优是一个复杂的过程,需要根据应用的特性和运行环境来调整不同的参数。常见的调优参数包括设置年轻代和老年代的内存大小、调整GC算法、设置GC触发的阈值等。对于高并发、低延迟的应用,可能需要关闭或...
3. **垃圾收集器和内存分配策略**: - `-XX:+UseConcMarkSweepGC` 和 `-XX:+UseParNewGC`:启用CMS(并发标记扫描)和ParNew垃圾收集器组合,适用于低延迟需求。 - `-XX:+UseG1GC`:使用G1(Garbage First)垃圾...
JVM调优的目标主要是优化堆内存分配、垃圾回收策略以及线程管理等。常见的问题包括内存泄漏、垃圾回收效率低下、Full GC频繁等。针对这些问题,我们可以调整JVM的启动参数,如-Xms和-Xmx设置初始堆和最大堆大小,-XX...
理解这些区域的作用和它们之间的关系对于调整对象生命周期和内存分配策略至关重要。 2. **垃圾收集器**:JVM内置了多种垃圾收集器,如Serial、Parallel、Concurrent Mark Sweep (CMS) 和G1。不同的垃圾收集器有不同...
WebLogic服务器内存调优是一个关键的过程,以...合理的内存分配可以避免频繁的垃圾收集,提高系统的响应速度,并确保服务的稳定性。在实践过程中,应监控内存使用情况,根据实际情况进行微调,以达到最佳的性能效果。
2. **收集基线数据**:通过JVisualVM、JConsole等工具监控应用的运行状态,了解当前的内存分配和垃圾回收情况。 3. **分析瓶颈**:通过GC日志和内存分析工具定位问题,如频繁Full GC、内存泄漏等。 4. **调整参数**...
JVM的内存调优还包括合理设定堆内存大小,避免频繁的垃圾回收,以及优化对象的创建和释放。 四、其他内存区域: 1. 每个线程都有自己的栈空间(Stack),其大小可以通过`-Xss`参数设置。栈的大小直接影响到可以同时...
JVM调优在此场景下可能需要关注对象创建频率、内存分配策略以及是否产生大量短生命周期的对象,这些都可能影响到GC行为。 总的来说,JVM调优是一个复杂而细致的过程,需要结合具体应用的性能指标和业务需求,通过...
不同的垃圾收集器有不同的内存分配策略。 4. **垃圾收集**:JVM提供了多种GC算法,如Serial、ParNew、Parallel Scavenge、CMS、G1和ZGC等,它们各有优缺点,适用于不同场景。 **GC详解** 1. **GC目标**:GC的主要...
合理的内存分配可以避免频繁的垃圾回收,提高应用响应速度。 2. **垃圾收集器选择**:不同的垃圾收集器有不同的性能特性,例如Serial、Parallel、CMS、G1、ZGC等。根据应用的特性和需求,选择合适的垃圾收集器至关...
系统和JVM调优是Java开发人员在面试中经常遇到的话题,这关乎程序性能优化、内存管理和稳定性。本文将深入探讨这两个关键领域的核心概念,并提供一些实战策略。 首先,我们来了解一下系统调优。系统调优主要包括...
1. **堆(Heap)**:这是Java对象的主要存储区域,所有的类实例和数组都会被分配到堆中。堆内存分为新生代(Young Generation)、老年代(Old Generation)和持久代(Permanent Generation)。新生代又细分为Eden区...
3. 内存分配策略:调整新生代、老年代的大小,减少Full GC的发生。 4. 类加载优化:合理设置-XX:MaxPermSize或-XX:MetaspaceSize,避免方法区溢出。 5. JIT编译优化:开启-XX:+UseConcMarkSweepGC或-XX:+UseG1GC等...
垃圾收集器与内存分配策略** 垃圾收集器是JVM内存管理的核心部分,它的主要任务是自动回收不再使用的对象所占用的内存空间。常见的垃圾收集器有Serial、ParNew、Parallel Scavenge、CMS(Concurrent Mark Sweep)、...