常见JVM参数配置和GC性能优化

常见的JVM参数配置

垃圾回收统计信息

-XX:+PrintGC     打印GC简要信息
-XX:+PrintGCDetails打印GC的详细信息
-XX:+PrintGCTimeStamps打印CG发生的时间戳
-Xloggc:log/gc.log 指定GC log的位置,以文件输出
-XX:+PrintHeapAtGC 每一次GC前和GC后,都打印堆信息。

堆设置

-Xms:初始堆大,最小堆
-Xmx:最大堆大小
-Xmn:设置新生代的大小
-XX:NewRatio新生代和年老代的比值,如为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代之和的1/4
-XX:SurvivorRatio设置两个Survivor区和eden的比值。注意Survivor区有两个。如:8,表示Eden:Survivor=8:2,一个Survivor区占整个年轻代的1/10
-XX:PermSize:设置永久区的初始空间
-XX:MaxPermSize:设置永久区的最大空间。
-XX:+MaxTenuringThreshold=10:新生代垃圾的最大年龄,代表对象在Survivor区经过10次复制以后才进入老年代。如果设置为0,则年轻代对象不经过Survivor区,直接进入老年代。
-XX:+PretenureSizeThreshold:设置大对象直接进入老年代的阈值。当对象的大小超过这个值时,将直接在老年代分配。 

栈的分配参数

-Xss:设置栈空间的大小

垃圾收集器设置

串行收集器的设置

-XX:+UseSerialGC:设置串行收集器,一般适用于小型应用和单处理器,算法比较简单,GC效率也较高,但可能会给应用带来停顿。

并行回收收集器设置(ParallelGC收集器的目标是达到一个可控制的吞吐量)

-XX:+UseParNewGC:设置年轻代为并行收集。
-XX:+UseParallelGC:设置年轻代使用并行回收收集器。多个线程并行执行GC,一般适用于多处理器系统中,可以提高GC的效率,但算法复杂,系统消耗较大。
-XX:+UseParalledlOldGC:设置老年代为并行回收收集器,Java1.6之后才出现。
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的线程数,最好与CPU数目相等。
-XX:MaxGCPauseMillis=n:设置年轻代每次并行垃圾回收的最大暂停时间。
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
-XX:+UseAdaptiveSizePolicy:自适应策略,自动选择年轻代区大小和相应的Survivor区比例。

CMS并发收集器(以最短停顿为目标)

-XX:+UseConcMarkSweepGC:使用CMS内存收集。
-XX:+ParallelCMSThreads: 设定 CMS 的线程数量。 
-XX:CMSFullGCsBeforeCompaction:CMS多少次后进行内存压缩,由于并发收集器不对内存空间进行压缩整理,所以运行一段时间以后会产生"碎片",使得运行效率降低。
-XX:+UseCMSCompactAtFullCollection:在FULL GC的时候,对年老代的压缩。CMS是不会移动内存的,因此,这个非常容易产生碎片,导致内存不够用,因此,内存的压缩这个时候就会被启用。可能会影响性能,但是可以消除碎片。
-XX:+CMSInitiatingOccupancyFraction:设置 CMS 收集器在老年代空间被使用多少后触发,默认为 68%。 
-XX:+CMSClassUnloadingEnabled:允许对类元数据进行回收。
-XX:+CMSParallelRemarkEndable:启用并行重标记。 
-XX:CMSInitatingPermOccupancyFraction:当永久区占用率达到这一百分比后,启动 CMS 回收 (前提是-XX:+CMSClassUnloadingEnabled 激活了)。 
-XX:UseCMSInitatingOccupancyOnly:表示只在到达阈值的时候,才进行 CMS 回收。 
-XX:+CMSIncrementalMode:使用增量模式,比较适合单 CPU。 

G1收集器

-XX:+UseG1GC:使用 G1 回收器。 
-XX:+UnlockExperimentalVMOptions:允许使用实验性参数。 
-XX:+MaxGCPauseMills:设置最大垃圾收集停顿时间。 
-XX:+GCPauseIntervalMills:设置停顿间隔时间。 

JVM的GC性能优化

对于GC的性能主要有2个方面的指标:吞吐量(工作时间不算,gc的时间占总的时间比)和暂停时间。

堆大小

默认情况下,vm会增加/减少heap大小以维持free space在整个vm中占的比例,这个比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。

一般而言,server端的app会有以下规则:

(1)对vm分配尽可能多的内存;
(2)将Xms和Xmx设为一样的值。如果虚拟机启动时设置使用的内存比较小,这个时候又需要初始化很多对象,虚拟机就必须重复地增加内存。
(3)处理器核数增加,内存也跟着增大。

年轻代

(1)对于程序流畅性运行影响的因素是新生代的大小。新生代越大,minor collection越少;但是在堆大小固定情况下,新生代越大就意味着越小的老年代,就意味着更多的major collection。
(2)8NewRatio反映的是新生代和老年代的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,将这两个值设为一样就固定了young generation的大小(同Xms和Xmx设为一样)。
(3)SurvivorRatio也可以优化survivor的大小,不过这对于性能的影响不是很大。SurvivorRatio是Eden和Survior大小比例。

一般而言,server端的app会有以下规则:

(1)首先决定能分配给vm的最大的堆大小,然后设定最佳的young generation的大小;
(2)如果堆大小固定后,增加新生代的大小意味着减小老年代大小。让老年代在任何时候够大,能够容纳所有存活的对象(留10%-20%的空余)。

年轻代大小选择

(1)响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制,在此种情况下,年轻代收集发生的频率也是最小的,同时,减少到达年老代的对象。
(2)吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度,因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。
(3)避免设置过小。当新生代设置过小时会导致:①YGC次数更加频繁;②可能导致YGC对象直接进入旧生代,如果此时旧生代满了,会触发FGC。

老年代大小选择

(1)响应时间优先的应用:年老代使用并发收集器。如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。一般需要参考以下数据:
         并发垃圾收集信息、持久代并发收集次数、传统GC信息、花在年轻代和年老代回收上的时间比例。
(2)吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。

较小堆引起的碎片问题

因为CMS年老代的并发收集器使用标记清除算法所以不会对堆进行压缩当收集器回收时,它会把相邻的空间进行合并,这样可以分配给较大的对象。但是,当堆空间较小时,运行一段时间以后,就会出现"碎片",如果并发收集器找不到足够的空间,那么并发收集器将会停止,可能需要进行如下配置:

-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩。

其他说明

(1)用64位操作系统,Linux下64位的jdk比32位jdk要慢一些,但是吃得内存更多,吞吐量更大

(2)XMX和XMS设置一样大,MaxPermSize和MinPermSize设置一样大,这样可以减轻伸缩堆大小带来的压力

(3)CMS的目标是最短的GC停顿时间,使用CMS的好处是用尽量少的新生代,然后老生代利用CMS并行收集,这样能保证系统低延迟的吞吐效率

(4)系统停顿的时候可能是GC的问题也可能是程序的问题,多用jmap和jstack查看,或者killall -3 java,然后查看java控制台日志,能看出很多问题

(5)如果用了缓存,那么年老代应该大一些,缓存的HashMap不应该无限制长,建议采用LRU算法的Map做缓存,LRUMap的最大长度也要根据实际情况设定

(6)采用并发回收时,年轻代小一点,年老代要大,因为年老代用的是并发回收,即使时间长点也不会影响其他程序继续运行,网站不会停顿

(7)JVM参数的设置(特别是 –Xmx –Xms –Xmn -XX:SurvivorRatio  -XX:MaxTenuringThreshold等参数的设置)没有一个固定的公式,需要根据PV old区实际数据、YGC次数等多方面来衡量。为了避免promotion faild可能会导致xmn设置偏小,也意味着YGC的次数会增多,处理并发访问的能力下降等问题。每个参数的调整都需要经过详细的性能测试,才能找到特定应用的最佳配置。

promotion failed:(晋升失败)

垃圾回收时promotion failed,一般可能是两种原因产生,第一个原因是To survivor救助空间不够,救助空间里的对象还不应该被移动到年老代,但年轻代又有很多对象需要放入救助空间;第二个原因是年老代没有足够的空间接纳来自年轻代的对象;这两种情况都会转向Full GC,网站停顿时间较长。

解决方案:

  • 第一个原因解决办法是去掉救助空间,设置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可,但是因为没有用到救助空间,所以年老代容易满,Full GC执行会比较频繁,所以可以把救助空间加大,这样也不会有promotion failed。
  • 第二个原因我的解决办法是设置CMSInitiatingOccupancyFraction为某个值(假设70),这样年老代空间到70%时就开始执行CMS,年老代有足够的空间接纳来自年轻代的对象。

实际编程中的性能优化

下面是一些在实际写程序的过程中应该注意的点:养成这些习惯可以在一定程度上减少内存的无谓消耗,进一步就可以减少因为内存不足导致GC不断。

(1)减少new对象。每次new对象之后,都要开辟新的内存空间。这些对象不被引用之后,还要回收掉。因此,如果最大限度地合理重用对象,或者使用基本数据类型替代对象,都有助于节省内存;
(2)多使用局部变量,减少使用静态变量。局部变量被创建在栈中,存取速度快。静态变量则是在堆内存;
(3)避免使用finalize,该方法会给GC增添很大的负担;
(4)如果是单线程,尽量使用非多线程安全的,因为线程安全来自于同步机制,同步机制会降低性能。例如,单线程程序,能使用HashMap,就不要用HashTable。同理,尽量减少使用synchronized
(5)用移位符号替代乘除号。eg:a*8应该写作a<<3
(6)对于经常反复使用的对象使用缓存;
(7)尽量使用基本类型而不是包装类型,尽量使用一维数组而不是二维数组;
(8)尽量使用final修饰符,final表示不可修改,访问效率高;
(9)单线程情况下(或者是针对于局部变量),字符串尽量使用StringBuilder,比StringBuffer要快;
(10)String为什么慢?因为String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象。如果不能保证线程安全,尽量使用StringBuffer来连接字符串。这里需要注意的是,StringBuffer的默认缓存容量是16个字符,如果超过16,apend方法调用私有的expandCapacity()方法,来保证足够的缓存容量。因此,如果可以预设StringBuffer的容量,避免append再去扩展容量。如果可以保证线程安全,就是用StringBuilder。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5627.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP客制化区域菜单和IMG配置清单

1. 自定义区域菜单 事务代码 SE43&#xff0c;操作如下 添加菜单对象 展示效果 输入区域菜单名称并回车&#xff0c;效果如下 2. 自定义IMG配置 事务代码 SIMGH IMG structure 示例-事务代码入口 示例-表格维护入口 示例-自定义代码控制对象 需要创建dummy表并设置表维护 页面设…

React、Vue框架如何实现组件更新,原理是什么?

引言 React 和 Vue 都是当今最流行的前端框架,它们都实现了组件化开发模式。为了优化性能,两者都采用了虚拟DOM技术。当组件状态发生改变时,它们会使用虚拟DOM进行局部渲染比对,只更新必要的DOM节点,从而避免重新渲染整个组件树。本文将从React和Vue的组件更新原理入手,剖析两…

Progressive Dual-Branch Network for Low-Light Image Enhancement 论文阅读笔记

这是22年中科院2区期刊的一篇有监督暗图增强的论文 网络结构如下图所示&#xff1a; ARM模块如下图所示&#xff1a; CAB模块如下图所示&#xff1a; LKA模块其实就是放进去了一些大卷积核&#xff1a; AFB模块如下图所示&#xff1a; 这些网络结构没什么特别的&#xf…

分布式光伏监控系统运维系统实时查看数据分布式光伏电站监控管理

光伏电站是一种利用太阳能发电的设施&#xff0c;随着人们对可再生能源的需求不断增加&#xff0c;光伏电站的建设也越来越普遍。但是&#xff0c;光伏电站的运营和管理需要高质量的监控系统来确保其正常运行。本文将介绍光伏电站监控系统的组成及其原理。 详细软件具体需求可…

冒泡排序与快速排序(交换排序)

目录 前言 一、冒泡排序 1.基本思想 2.冒泡排序&#xff1a; 3.代码实现&#xff1a; 二、快速排序 1. 概念&#xff1a; 2.三种实现&#xff1a; 3.代码实现&#xff1a; 4.优化: 前言 所谓交换&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两个记录在序…

【二等奖方案】基于人工智能的漏洞数据分类赛题「道可道,非常道」团队解题思路

2022 CCF BDCI 大赛 数字安全公开赛「基于人工智能的漏洞数据分类」赛题二等奖团队「道可道&#xff0c;非常道」战队获奖方案&#xff0c;赛题地址&#xff1a; http://go.datafountain.cn/s57 团队简介 本团队具有丰富的比赛和项目经验。在AI大赛上多次拿到Top成绩&#xf…

FFMPEG源码之过滤器

功能介绍 FFmpeg的过滤器是用于对音视频流进行处理和转换的模块。它可以对输入流进行各种操作&#xff0c;如调整大小、调节亮度、对比度、裁剪、旋转等。 操作步骤 实现对某个视频的放大操作的详细步骤如下&#xff1a; 配置和初始化FFmpeg&#xff1a;在开始编写代码之前…

线性表之链表

1、链表概述 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 顺序表的存储位置可以用一个简单直观的公式表示&#xff0c;它可以随机存取表中任意一个元素&#xff0c;但插入和删除需要移动大量元素。链式…

深入理解 PostgreSQL 的架构和内部工作原理

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Postman怎么做接口测试-以简单的登录接口为例

我们就以登录某测试系统为例子&#xff0c;实现在Postman上做接口测试 一、首先打开系统首页首页&#xff0c;做一个登录操作&#xff08;目的是获取接口url及参数&#xff09;&#xff1a;一般在公司做接口测试的时候页面还没有出来&#xff0c;我们需要根据接口文档进行接口…

kafka第三课-可视化工具、生产环境问题总结以及性能优化

一、可视化工具 https://pan.baidu.com/s/1qYifoa4 密码&#xff1a;el4o 下载解压之后&#xff0c;编辑该文件&#xff0c;修改zookeeper地址&#xff0c;也就是kafka注册的zookeeper的地址&#xff0c;如果是zookeeper集群&#xff0c;以逗号分开 vi conf/application.conf 启…

Python 逻辑回归:理论与实践

文章目录 1. 介绍1.1 什么是逻辑回归&#xff1f;1.2 逻辑回归的应用领域 2. 逻辑回归的原理2.1 Sigmoid 函数2.2 决策边界2.3 损失函数 3. 逻辑回归的实现3.1 数据准备3.2 创建逻辑回归模型3.3 模型训练3.4 模型预测3.5 模型评估 4. 可视化决策边界4.1 绘制散点图4.2 绘制决策…

基于SaaS模式的Java基层卫生健康云HIS系统源码【运维管理+运营管理+综合监管】

云HIS综合管理平台 一、模板管理 模板分为两种&#xff1a;病历模板和报表模板。模板管理是运营管理的核心组成部分&#xff0c;是基层卫生健康云中各医疗机构定制电子病历和报表的地方&#xff0c;各医疗机构可根据自身特点特色定制电子病历和报表&#xff0c;制作的电子病历…

php 手机加*星 【字符串】

场景&#xff1a;展示手机号时&#xff0c;避免暴露隐私信息&#xff0c;因此需要给手机号加*号 代码 /*** 手机号码隐私加星* param string $mobile 手机号*/ function mobileToStar(string $mobile) { // 正则检测手机号if(!preg_match(/^1[3456789]\d{9}$/,$mobile)){// …

Docker 容器生命周期:创建、启动、暂停与停止----从创建到停止多角度分析

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Sysbench测试工具详解

文章目录 Sysbench安装准备测试数据使用yum安装的路径进行测试测试结果 Sysbench Sysbench 是一个常用的多线程性能测试工具&#xff0c;可用于评估数据库系统和硬件的性能。它支持多种基准测试&#xff0c;包括 OLTP (Online Transaction Processing)、CPU、文件 I/O、内存等。…

代码随想录| 图论04 查并集 ●查并集理论知识 ●1971.寻找图中是否存在路径 ●684.冗余连接 ●685.冗余连接II

#查并集理论知识 并查集用处&#xff1a;解决连通性问题 将两个元素添加到一个集合中。判断两个元素在不在同一个集合 思路&#xff1a;将三个元素A&#xff0c;B&#xff0c;C &#xff08;分别是数字&#xff09;放在同一个集合&#xff0c;其实就是将三个元素连通在一起&a…

Python 算法基础篇:插入排序和希尔排序

Python 算法基础篇&#xff1a;插入排序和希尔排序 引言 1. 插入排序算法概述2. 插入排序算法实现实例1&#xff1a;插入排序 3. 希尔排序算法概述4. 希尔排序算法实现实例2&#xff1a;希尔排序 5. 插入排序与希尔排序的对比总结 引言 插入排序和希尔排序是两种常用的排序算法…

017-从零搭建微服务-系统服务(四)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…

【实战】 七、Hook,路由,与 URL 状态管理(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(十三)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…