- 浏览: 90286 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
hairongtian:
我想问一下在GC中的gc roots是什么?教科书的看不懂,能 ...
JVM-GC实践总结(纠正并发线程数 转载)
首先感谢阿宝同学的帮助,我才对这个gc算法的调整有了一定的认识,而不是停留在过去仅仅了解的阶段。在读过sun的文档和跟阿宝讨论之后,做个小小的总结。
CMS,全称Concurrent Low Pause
Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求
大于对吞吐量的要求,能够承受垃圾回收线程和应用线程共享处理器资源,并且应用中存在比较多的长生命周期的对象的应用。CMS是用于对tenured
generation的回收,也就是年老代的回收,目标是尽量减少应用的暂停时间,减少full
gc发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代。在我们的应用中,因为有缓存的存在,并且对于响应时间也有比较高的要求,因此希
望能尝试使用CMS来替代默认的server型JVM使用的并行收集器,以便获得更短的垃圾回收的暂停时间,提高程序的响应性。
CMS并非没有暂停,而是用两次短暂停来替代串行标记整理算法的长暂停,它的收集周期是这样:
初始标记(CMS-initial-mark) -> 并发标记(CMS-concurrent-mark) ->
重新标记(CMS-remark) -> 并发清除(CMS-concurrent-sweep)
->并发重设状态等待下次CMS的触发(CMS-concurrent-reset)。
其中的1,3两个步骤需要暂停所有的应用程序线程的。第一次暂停从root对象开始标记存活的对象,这个阶段称为初始标记;第二次暂停是在并发标记之后,
暂停所有应用程序线程,重新标记并发标记阶段遗漏的对象(在并发标记阶段结束后对象状态的更新导致)。第一次暂停会比较短,第二次暂停通常会比较长,并且
remark这个阶段可以并行标记。
而并发标记、并发清除、并发重设阶段的所谓并发,是指一个或者多个垃圾回收线程和应用程序线程并发地运行
,垃圾回收线程不会暂停应用程序的执行,如果你有多于一个处理器,那么并发收集线程将与应用线程在不同的处理器上运行,显然,这样的开销就是会降低应用的吞吐量。Remark阶段的并行
,是指暂停了所有应用程序后,启动一定数目的垃圾回收进程进行并行标记,此时的应用线程是暂停的。
CMS的young generation的回收采用的仍然是并行复制收集器,这个跟Paralle gc算法是一致的。
下面是参数介绍和遇到的问题总结,
1、启用CMS:-XX:+UseConcMarkSweepGC
。 咳咳,这里犯过一个低级错误,竟然将+号写成了-号
2。CMS默认启动的回收线程数目是 (ParallelGCThreads + 3)/4) ,如果你需要明确设定,可以通过-XX:
ParallelCMSThreads
=20来设定,其中
ParallelGCThreads是年轻代的并行收集线程数
3、CMS是不会整理堆碎片的,因此为了防止堆碎片引起full gc,通过会开启CMS阶段进行合并碎片选项:-XX:+UseCMSCompactAtFullCollection
,开启这个选项一定程度上会影响性能,阿宝的blog里说也许可以通过配置适当的CMSFullGCsBeforeCompaction来调整性能,未实践。
4.为了减少第二次暂停的时间,开启并行remark: -XX:+CMSParallelRemarkEnabled
,如果remark还是过长的话,可以开启-XX:+CMSScavengeBeforeRemark
选项,强制remark之前开始一次minor gc,减少remark的暂停时间,但是在remark之后也将立即开始又一次minor gc。
5.为了避免Perm区满引起的full gc,建议开启CMS回收Perm区选项:
+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
6.默认CMS是在tenured generation沾满68%的时候开始进行CMS收集,如果你的年老代增长不是那么快,并且希望降低CMS次数的话,可以适当调高此值:
-XX:CMSInitiatingOccupancyFraction=80
这里修改成80%沾满的时候才开始CMS回收。
7.年轻代的并行收集线程数默认是(ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8)
,如果你希望设定这个线程数,可以通过-XX:ParallelGCThreads=
N 来调整。
8.进入重点,在初步设置了一些参数后,例如:
- XX:MaxPermSize = 64m - XX: - UseConcMarkSweepGC - XX: + UseCMSCompactAtFullCollection
- XX:CMSInitiatingOccupancyFraction = 80 - XX: + CMSParallelRemarkEnabled
- XX:SoftRefLRUPolicyMSPerMB = 0
需要在生产环境或者压测环境中测量这些参数下系统的表现,这时候需要打开GC日志查看具体的信息,因此加上参数:
-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/home/test/logs/gc.log
在运行相当长一段时间内查看CMS的表现情况,CMS的日志输出类似这样:
4391.352 : [CMS - concurrent - mark - start]
4391.779 : [CMS - concurrent - mark: 0.427 / 0.427 secs] [Times: user = 1.24 sys = 0.31 , real = 0.42 secs]
4391.779 : [CMS - concurrent - preclean - start]
4391.821 : [CMS - concurrent - preclean: 0.040 / 0.042 secs] [Times: user = 0.13 sys = 0.03 , real = 0.05 secs]
4391.821 : [CMS - concurrent - abortable - preclean - start]
4392.511 : [CMS - concurrent - abortable - preclean: 0.349 / 0.690 secs] [Times: user = 2.02 sys = 0.51 , real = 0.69 secs]
4392.516 : [GC[YG occupancy: 111001 K ( 235968 K)] 4392.516 : [Rescan (parallel) , 0.0309960 secs] 4392.547 : [weak refs processing, 0.0417710 secs] [ 1 CMS - remark: 655734K(1310720K)] 766736K(1546688K), 0.0932010 secs] [Times: user = 0.17 sys = 0.00 , real = 0.09 secs]
4392.609 : [CMS - concurrent - sweep - start]
4394.310 : [CMS - concurrent - sweep: 1.595 / 1.701 secs] [Times: user = 4.78 sys = 1.05 , real = 1.70 secs]
4394.310 : [CMS - concurrent - reset - start]
4394.364 : [CMS - concurrent - reset: 0.054 / 0.054 secs] [Times: user = 0.14 sys = 0.06 , real = 0.06 secs]
其中可以看到CMS-initial-mark阶段暂停了0.0303050秒,而CMS-remark阶段暂停了0.0932010秒,因此两次暂停的总共时间是0.123506秒,也就是123毫秒左右。两次短暂停的时间之和在200以下可以称为正常现象。
但是你很可能遇到两种fail引起full gc
:Prommotion failed和Concurrent mode failed。
Prommotion failed的日志输出大概是这样:
2166784K), 9.2214860 secs] 1458785K -> 1120688K(2520704K), 9.4584090 secs]
这个问题的产生是由于救助空间不够,从而向年老代转移对象,年老代没有足够的空间来容纳这些对象,导致一次full gc的产生。解决这个问题的办法有两种完全相反的倾向:增大救助空间、增大年老代或者去掉救助空间
。
增大救助空间就是调整-XX:SurvivorRatio参数,这个参数是Eden区和Survivor区的大小比值,默认是32,也就是说Eden区是
Survivor区的32倍大小,要注意Survivo是有两个区的,因此Surivivor其实占整个young
genertation的1/34。调小这个参数将增大survivor区,让对象尽量在survitor区呆长一点,减少进入年老代的对象。去掉救助空
间的想法是让大部分不能马上回收的数据尽快进入年老代,加快年老代的回收频率,减少年老代暴涨的可能性,这个是通过将-XX:SurvivorRatio
设置成比较大的值(比如65536)来做到。在我们的应用中,将young
generation设置成256M,这个值相对来说比较大了,而救助空间设置成默认大小(1/34),从压测情况来看,没有出现prommotion
failed的现象,年轻代比较大,从GC日志来看,minor gc的时间也在5-20毫秒内,还可以接受,因此暂不调整。
Concurrent mode failed的产生是由于CMS回收年老代的速度太慢,导致年老代在CMS完成前就被沾满,引起full gc,避免这个现象的产生就是调小-XX:CMSInitiatingOccupancyFraction
参数的值,让CMS更早更频繁的触发,降低年老代被沾满的可能。我们的应用暂时负载比较低,在生产环境上年老代的增长非常缓慢,因此暂时设置此参数为80。在压测环境下,这个参数的表现还可以,没有出现过Concurrent mode failed。
发表评论
-
JVM 运行时数据区(转)
2012-07-11 23:02 1052运行时数据区 java虚拟机定义了若干种程序运行时使用 ... -
图解JVM 内存分配
2012-07-10 23:57 12131.简介 现摘录一段Java5 ... -
深入Java虚拟机:JVM中的Stack和Heap
2012-07-10 14:26 1092在JVM中,内存分为两个部分,Stack(栈)和He ... -
JVM分代垃圾回收策略的基础概念
2012-07-10 13:50 1358由于不同对象的生命周期不一样,因此在JVM的垃圾回收策略中 ... -
Java虚拟机(JVM)中的内存设置详解(转载)
2012-07-09 17:13 1129在一些规模稍大的应用 ... -
JVM原理_内存篇(转载)
2012-07-09 16:56 2159一、JVM简介 ... -
JVM参数调优的八条经验(转载)
2012-07-09 14:35 953要想配置好JVM参数,需要对年轻代、年老代、救助空间和永久代有 ... -
Tomcat负载均衡原理详解及配置(Apache2.2.19+Tomcat7.0.12)
2012-06-30 11:45 1229使用Tomcat的童鞋们注意了。为了增加tomcat的性能和稳 ... -
Tomcat和Terracotta服务器将普通的Web应用部署到集群中,实现跨Tomcat节点的session复 制
2012-06-30 11:31 1349本文介绍如何配置Tomcat和Terracotta服务器将普通 ... -
tomcat session 持久化会话
2012-06-30 11:29 1599tomcat6 中关闭服务 会自动把session持久化 ... -
Tomcat集群Session丢失解决方案
2012-06-29 01:38 4405这几天单服务器整合项目很正常,集群的时候问题就来了,配 ... -
nginx+tomcat集群+session复制
2012-06-29 01:34 1237ulimit -SHn 65535 echo " ... -
linux下的并发数量
2012-06-26 21:32 964在部署系统后,为了增加系统并发量,系统响应速度,做了一些 ... -
网站的静态化处理
2012-06-26 21:10 863urlrewritefilter 下载: htt ... -
linux+nginx+tomcat负载均衡,实现session同步
2012-06-21 15:18 3895花了一个上午的时间研究nginx+tomcat的负载均衡测试, ... -
tomcat6_apache2.2_ajp负载均衡加集群实战 [转]
2012-04-26 16:07 932秀脱linux笔记之tomcat6_apa ... -
JVM内存最大能调多大分析-转帖
2012-02-18 12:48 1387JVM内存最大能调多大分析【经典】 上次用webl ... -
nginx for windows之负载均衡
2011-05-06 17:53 9621.编辑c:\nginx\conf\nginx.conf ... -
Tomcat6性能调优 出现java.lang.OutOfMemoryError: PermGen space
2010-08-03 13:51 1375Tomcat6在部署应用中,Server报错:java.lan ... -
APACHE 2.2.8+TOMCAT6.0.14配置负载均衡
2010-01-21 02:11 0目标: 使用 apache 和 tomcat ...
相关推荐
6. **并行与并发调整**:根据系统硬件资源调整并行GC的线程数(`-XX:ParallelGCThreads`),以及并发GC的并发程度(`-XX:ConcGCThreads`),以达到最佳性能。 7. **类加载器管理**:类加载器的不当使用可能导致内存...
例如,Serial GC适合单线程环境,Parallel GC提高了并行性,CMS在低停顿时间方面表现出色,而G1则尝试在整个堆上进行并行和并发的垃圾收集。 "jvm-full-gc.zip"中的示例可能涵盖如何通过配置JVM参数来调整垃圾收集...
Java虚拟机(JVM)是Java程序运行的基础,它的核心组成部分之一就是垃圾收集器(GC)。GC全面知识系统详解涵盖了JVM内存结构、垃圾回收机制、类加载与字节码技术以及内存模型等多个重要主题。 首先,我们来探讨JVM...
7. **多线程与并发**:讲解JVM中的线程创建、同步机制(如synchronized、Lock),以及并发容器(如ConcurrentHashMap)的实现原理。 8. **类文件结构**:分析.class文件的组成,包括魔数、版本号、常量池、访问标志...
"jvm-demo"可能包含各种GC策略的示例,如Minor GC、Major GC和Full GC,以及如何调整GC参数以优化性能。 5. **JVM性能调优** 通过监控和分析JVM的运行情况,我们可以进行性能优化。这可能涉及到堆大小的设置、...
#### JUC多线程及高并发 Java并发编程包(java.util.concurrent,简称JUC)封装了大量用于高并发编程的工具类和接口,其中涉及了线程池、阻塞队列、同步器、原子操作类等。在并发环境下,可以有效降低线程创建和管理...
7. **线程与并发**:JVM中的线程管理涉及到线程池配置(如通过-XX:ThreadStackSize设定线程栈大小,-XX:ParallelThreads控制并行GC线程数),以及并发工具类的使用,如Semaphore、CyclicBarrier等。 8. **代码优化*...
- 操作栈:每个线程都有一个独立的操作栈,用于存储方法调用的局部变量、操作数栈等。 - PC寄存器:记录当前线程正在执行的字节码指令地址。 - 方法区和运行时常量池:存储类和接口的常量、方法信息。 2. **内存...
### JVM-Tomcat线程-数据库连接池设置建议 #### 一、JVM参数设置 在设置JVM参数时,我们需要遵循一定的原则以确保应用程序能够高效稳定地运行。以下是一些具体的设置指南: 1. **Java堆大小设置**: - `Xmx` 和 ...
7. **并发与多线程**:JVM如何处理并发,包括线程同步、锁机制、线程池的配置与优化。 8. **JIT编译器**:介绍JVM的即时编译器(Just-In-Time Compiler),它将热点代码编译为机器码以提高执行效率。 9. **内存...
### JVM_GC调优详解 #### 一、JVM体系结构概览 Java虚拟机(JVM)作为Java程序的运行环境,其内部结构复杂且高效。为了更好地理解JVM_GC调优,我们首先来了解一下JVM的基本组成部分。 1. **类装载器子系统(Class ...
1. **Java虚拟机栈**:每个线程都有一个独立的虚拟机栈,用于存储方法调用的局部变量表、操作数栈、动态链接和方法出口等信息。当方法调用结束,对应的栈帧也会被清除。 2. **堆**:所有对象实例都在堆中分配内存,...
- **栈**:每个线程都有一个独立的栈,用于存储方法调用时的局部变量表、操作数栈、动态链接和方法出口等信息。 - **方法区**:存储类信息、常量、静态变量等,Java 8后被元空间替代,元空间位于本地内存中,可以...
在深入探讨JVM(Java虚拟机)的理论与实践结合时,我们首先需要理解JVM在Java编程中的核心地位。JVM是Java平台的核心组成部分,它负责执行编译后的Java字节码,使得Java程序具有跨平台的特性。在"理论与实践结合 ...
3. **并行与并发设置**:调整并行GC线程数和并发GC策略,优化性能。 4. **对象存活率预估**:通过调整Survivor区比例,减少Full GC的发生。 5. **内存分配策略**:如使用CMS或G1等高级GC算法,降低STW影响。 此外,...
《深入理解JVM & G1 GC》这篇文章和相关压缩包文件主要聚焦于Java虚拟机(JVM)的内存管理,特别是垃圾收集器(GC)的优化,特别是G1(Garbage-First)垃圾收集器的深度解析。下面将详细阐述JVM、GC的基本概念,...
本文将深入探讨“WAS性能调优对jvm、线程数、ORB大小的配置”这一主题。 首先,我们要理解JVM(Java Virtual Machine)在WAS中的作用。JVM是Java程序运行的平台,它的性能直接影响到应用的响应时间和资源利用率。在...
- **栈容量调整**:根据应用的并发情况,适当调整线程栈大小,防止StackOverflowError。 - **局部变量复用**:避免无谓的对象创建,减少栈上空间消耗。 3. **运行时常量池优化**: - **静态常量合并**:减少常量...
2. 并发、并行收集(Parallel, Concurrent, Collection):JVM 的收集机制能够并发地执行垃圾回收,提高系统的响应速度和吞吐量。 3. 低总分配成本(Low total allocation cost):JVM 的内存分配机制能够尽量减少...
总结来说,"thread-gc-分析"这个主题涵盖了JVM线程的管理与优化,以及垃圾收集的原理与调优。理解这些知识点对于提升Java应用的性能至关重要。在实际工作中,我们需要根据应用的特点和需求,合理配置JVM参数,选择...