热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

tomcat调优配置

今天遇到一个tomcat服务注册后配置Java参数没效果,最后在注册表中删除原来的tomcat服务后,顺便看了一下tomcat的调优配置,

今天遇到一个tomcat服务注册后配置Java参数没效果,最后在注册表中删除原来的tomcat服务后,顺便看了一下tomcat的调优配置,看别人总结的不错,就转载一下。

Tomcat、Jetty、GlassFish 等等这系列 Web容器/应用服务器,虽然做为容器,提供的是一个 Java Web 的运行时环境,以支持Servlet/JSP 等等这些内容的运行,但我们都很清楚,其本质上还是一个 Java 应用程序。 每次对于 容器的启动运行,都是把这个 Java 程序跑起来,来实现 Web 容器的能力。

 

做为一类“特殊”的 Java 应用程序,和任务其他的 Java 应用一样,需要使用到JVM,会有堆,会使用到垃圾回收,会涉及到不同的堆分区比例...  

因此在对Web 容器( 应用服务器) 的调优中必不可少的是对于 JVM 的调优。

 

 

对于 JVM 的调优,主要有两个方面考虑:

 

内存大小配置

垃圾回收算法选择

 

当然,确切的说,以上两点并不互相独立,内存的大小配置也会影响垃圾回收的执行效率。

 

其中内存大小配置,最主要做的有

 

确定内存占用的总大小

确定内存中各个代(Gen) 的大小划分

 

 

内存大小配置

 

所谓内存大小的占用,是指应用程序启动后稳定运行一小段时间时,观察到的内存占用情况。

以 HotSpot 虚拟机为例,Java 堆主要有三个空间:

新生代、老年代和永久代。 

 

根据不同应用的特别,观察应用对于内存的占用,如果有大量的临时对象,不会重复使用,则可以调整 New Gen, 这样这些临时对象就在新生代创建完成,并在 Minor GC 产生时被回收,这样较短生存活的对象不会晋升到老年代,从而可以避免垃圾堆集产生 Full GC。 

 

理想状态下,短期存活的对象都只在新生代完成生命周期,被费时劲少的 

Minor GC 回收完成, 而长期存活,将会多次使用的在多次回收之后晋升到老年代, 最终经过 Full GC 完成生命周期。

 

这里涉及到关于内存大小的调整参数有:

 

-Xms

-Xmx

 

这两个参数用于配置 heap 的起始大小和最大值。这里需要经过观察,找一个合适的值,设置太大会导致内存浪费,同时也会导致垃圾回收耗时太长。对于 Tomcat 来说,一般都会将初始值和最大值设置为相同值,这样就避免在初始内存不足时触发 Full GC 来进行扩展内存。

 

设定 heap 大小之后,要根据对象生命周期的特征,来调整新生代与老年代的大小比例。

 

涉及到的参数有:

-XX:NewSize

-XX:NewRatio

-XX:MaxNewSize

-Xmn

 

第一个是直接设置新生代初始大小,第二个是设置比例(Ratio)。太高或太低都会导致 GC 不能高效的工作。毕竟 Minor GC 也是要耗时的。最后一个设置新生代的初始值和最大值相同,堆空间的变化不影响其值。

 

对于使用了大量第三方类库的应用来说,会加载许多框架依赖的类,使用过程中可能会遇到因为Perm Gen 不足产生的 OOM,这种情况可以通过观察稳定状态下 Perm 区的占用,再通过参数设置。

 

-XX:PermSize

-XX:MaxPermSize

-XX:MaxMetaspaceSize

 

第一个会设置Perm区的初始大小,第二个用于设置Perm 区的最大值。在Java 8的时候, Perm 区被移除,改为Metaspace,不过如果遇到类似的OOM,依然可以调整其大小。

 

此外,对于使用大量线程的应用,也可以配置 -Xss,主要用于设置单个线程的stack 大小。注意,是单个的大小,因此设置值越大,会占用越大,可用的线程数也就越少。

 

这里的配置一般对于-X开始的可以直接在后面用数字加单位,而-XX的则需要等号后数字再加单位,例如:

java -Xms100m -Xmx200m -XX:PermSize=300m

 

这里数字后的单可以是m,g,k代表计算机中的不同单位。

 

那我们前面一直在说根据不同的应用,观察分析设置堆的大小,堆的各个代的大小,那具体观察什么呢?

 

我们一般在JVM的配置中增加一些打印 GC 日志的选项,配置方式和上面的类似,这样在 GC 产生时,会打印出各个代占用的大小,具体触发时间等。推荐的配置有以下几个:

 

-XX:+PrintGCTimeStamps

-XX:+PrintGCDetails

-Xloggc:<文件名>

-XX:PrintGCDateStamps

 

第一个和第四个选项可以任选一个&#xff0c;第一个打印自JVM启动以来的时间&#xff0c;一般也称为uptime, 第四个打印的是系统当前日期和时间。

 

根据 GC 日志产生的内容&#xff0c;来观察具体的大小&#xff0c;开始使用上述的配置参数进行调整。当然&#xff0c;也可以用 JConsole, JVisual VM 这些工具可视化的进行了解再调整。工具的使用可以参考历史文章

Java七武器系列多情环 --多功能Profiling工具 JVisual VM

 

 

垃圾回收算法

 

不同的垃圾回收算法&#xff0c;对于应用的影响很大。一方面可能在一个服务器上却使用了单线程的回收算法&#xff0c;也可能应用对于响应要求很高&#xff0c;但却使用了一个吞吐量优先的算法&#xff0c;导致响应太慢。

所以对于垃圾回收算法的选择&#xff0c;一般都是根据应用的特点&#xff0c;是要低延迟还是高吞吐量&#xff0c;选择合适的算法。我们前面也提到&#xff0c;垃圾回收算法和内存的大小配置并非独立的&#xff0c;内存设置大是回收的频率会降低&#xff0c;但每次的执行时间也会变长。所以这里也是一个需要权衡的地方。

 

延迟、吞吐量调优

其他 JVM 配置

 

垃圾回收算法对应到的就是不同的垃圾收集器&#xff0c;具体到在 JVM 中的配置&#xff0c;是使用 -XX:&#43;UseParallelOldGC 或者 -XX:&#43;UseConcMarkSweepGC 这种不同的收集器来达到选择算法的目的。

 

其中 ParallelGC 也称为 吞吐量优先收集器&#xff0c;可以提升应用的吞吐量&#xff0c;但在老年代大小调整之&#xff0c;进行几次垃圾回收后&#xff0c;不能满足应用的低延迟要求。

一般常用到ConcMarkSweepGC&#xff0c; 也称之为 CMS GC&#xff0c;其可以做到老年代的垃圾回收与应用程序的纯种并行执行&#xff0c;所以可以实现低延迟。

 

这里注意&#xff0c;由于 CMS GC 和其他GC回收算法使用的框架不同&#xff0c;因此不能混用&#xff0c;在使用CMS 进行老年代回收时&#xff0c;新生代默认使用了单线程回收算法&#xff0c;此时可以通过配置 -XX:&#43;UseParNewGC来使用 新生代并行回收。

 

由于CMS是垃圾回收和应用线程并行&#xff0c;因此需要额外的CPU处理资源&#xff0c;如果只有一个CPU的机器&#xff0c;或者有多个忙碌的CPU&#xff0c;又想要使用低延迟的收集器&#xff0c;此时可以通过配置 CMS 收集器的增量模式来进行回收&#xff0c;通过指定 -XX:&#43;CMSIncrementalMode 来开启增量模式。此时交替运行垃圾收集器应用线程。通过配置 

-XX:CMSIncrementalSafetyFactor&#61;X&#xff0c; -XX:CMSIncrementalDutyCycleMin&#61;Y,

-XX:CMSIncrementalPacing 可以控制垃圾收集后台线程为应用线程让出多少CPU周期。

 

参数-XX:&#43;CMSParallelRemarkEnabled 用来降低标记停顿&#xff0c;另外由于CMS 回收后的老年代内存空间并不是连续的&#xff0c;因此通过参数

-XX:&#43;UseCMSCompactAtFullCollection 在Full GC的时候对年老代的压缩。

 

在JDK1.7 的时候引入了 G1 收集器&#xff0c;可以通过配置-XX:&#43;UseG1GC 来开启。这一方面的实战经验不多&#xff0c;有相关使用经验的朋友欢迎分享。

 

此外&#xff0c;还可以对新生代进行更细致的配置&#xff0c;比如设置Eden 和 Suvivor 区的比例等&#xff0c;和Newxx类似&#xff0c;可以通过SuvivorRation设置比例。

 

 

其他 JVM 配置

 

可以使用 -XX:&#43;DisableExplicitGC 选项来禁止显式的 System.gc 的调用。这个使用时需要评估后再使用。

 

所谓调优&#xff0c;就是一个不断调整和优化的过程&#xff0c;需要观察、配置、测试再如此重复。有相关经验的朋友欢迎留言补充&#xff01;

 

说到底&#xff0c;那上面的这些选项是要配置在哪里呢&#xff1f; 我们前面提到 Tomcat 本质也是个普通的 Java 应用&#xff0c;因此和一般的 Java 启动方式类似&#xff0c;也是类似 

 

java -Xms100m -XX:&#43;UseParallelOldGC 应用主类

 

通过这种形式来启动&#xff0c;区别只是 Tomcat 将上述命令放到了文件中&#xff0c;对应到不同的操作系统&#xff0c;Windows下使用 bat文件&#xff0c; Linux下使用 sh 文件。

 

所以我们的配置项也是加到这些文件中。

 

我们来看catalina.sh中实际启动时执行的命令&#xff1a;

 

 

 

所以我们的选项可以加到 

JAVA_OPTS

CATALINA_OPTS

这些可选项中。

配置比较简单&#xff0c;例如下面这样&#xff1a;

 

 

配置的时候需要特别注意的是&#xff0c;不要把前面已经有的配置冲掉&#xff0c;比如

在配置JAVA_OPTS的时候&#xff0c;要把前面已经配置的加上&#xff0c;写起来是这样&#xff1a;

JAVA_OPTS&#61;"$JAVA_OPTS 新增的内容"

 




推荐阅读
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
author-avatar
好的吧
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有