性能测试三十六:内存溢出和JVM常见参数及JVM参数调优
堆内存溢出:
此种溢出,加内存只能缓解问题,不能根除问题,需优化代码
堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,就会出现内存溢出OutOfMemory:Java heap space
永久代溢出
如果发生,则是在初始化的时候,空间太小,解决办法,扩大空间
类的一些信息,如类名、访问修饰符、字段描述、方法描述等,所占空间大于永久代最大值,就会出现OutOfMemoryError:PermGen space
内存溢出的检测方法:pid=1730

Jdk/bin目录下有很多检测工具
图形界面:
Jconsole
Jvisualvm
命令行工具:
Jstat –gcutil pid 1000 100 (只需要看O,如果达到100%,并且长期处于100%,则代表老年代内存不足)
pid:进程号、1000:1秒钟获取一次、100一共获取100次
E:eden区
O:老年代
P:永久代
YGC:新生代的GC次数
YGCT:当前统计的YGC一共花费的时间(毫秒)
FGC:fullGC老年代的GC次数
FGCT:当前统计的FGC一共花费的时间(毫秒)
GCT:YGC+FGC

Jmap –histo pid | head -20
把当前JVM里面的所有对象打印出来,排序,head:头部,head -20 前20行

Jmap –heap pid(列出当前进程的堆的数据,一般用来看当前配置)


在jvisualvm上面也可以看到JVM参数


FullGC频率:单次FullGC时间<200ms
Jvm常见参数
-Xms2048m,初始堆大小,建议<物理内存的1/4,默认值为物理内存的1/64
-Xmx2048m,最大堆大小,建议与-Xms保持一致,默认值为物理内存的1/4
-Xmn512m,新生代大小,建议不超过堆内存的1/2
-Xss256k,线程年轻代堆栈大小,建议256k
-XX:PermSize=256m,永久代初始值,默认值为物理内存的1/64
-XX:MaxPermSize=256m,永久代最大值,默认值为物理内存的1/4
-XX:SurvivorRatio=8:年轻带中Eden区和Survivor区的比例,默认为8:1:1,即Eden(8),From Space(1),ToSpace(1)
-XX:+UseConcMarkSweepGC:开启CMS垃圾回收器
看一下内存溢出的情况
先配置一下tomcat里面JVM的参数:vi /home/server/tomcat-PerfTeach01/bin/catalina.sh


由于ip变了,改一下host里面的ip


启动tomcat

能访问,代表启动成功:http://localhost:8080/PerfTeach/MemoryLeak?userId=123&password=abc&waitTime=3

jmeter5个并发永远跑

TPS

响应时间

cpu

jstat -gcutil 1730 1000 1000

jvisualvm

看一下tomcat日志的后200行

有内存溢出的报错

看当前JVM里面的所有对象,找com开头的,业务代码,再找非java开头的
可以看出org.apache可能有问题,com.lee是业务代码,一定有问题
直接告诉开发,让开发去解决
jvisualvm也可以生成快照,一开始出现内存泄漏的时候就点堆Dump在服务器下生成快照,下载后再用 jvisualvm打开, jvisualvm_文件_装入_文件类型选“线程 Dump”


由于这个内存泄漏的原因其实是session引起的,所以最好把tomcat的session持久化取消掉,以免下次启动tomcat又加载上一次保留的session
修改:tomcat目录下conf/context.xml,将 <Manager pathname="" />这行的注释打开

把注释打开


内存泄漏的本质:老年代空间里面东西放满了,又不能被回收
程序一旦出现内存泄漏,就算停止压测也不能解决,只能重启
内存泄露会出现的现象
1,tps出现大幅波动,并慢慢降低,甚至降为0,响应时间随之波动,慢慢升高
2,通过jstat命令看到,Jvm中Old区不断增加,FullGC非常频繁,对应的FullGC消耗的时间也不断增加
3,通过jconsole/jvisualvm可以看到,堆内存曲线不断上升,接近上限时,变成一条直线
4,日志报错java.lang.OutOfMemoryError: Java heap space
内存泄露定位
1,通过jmap命令:jmap -histo pid | head -20,查看当前堆内存中实例数和占用内存最多的前20个对象
2,通过jvisualvm,进行远程堆dump,然后把dump文件下载下来,用jvisualvm打开进行分析,可以看到更直观的jvm中对象的信息
监控内存泄露问题的场景
1,在试压阶段,或任意场景都可以考虑通过jvisualvm和jstat监控jvm的情况
2,在稳定性场景中,一定要关注Jvm内存使用的情况,在长时间的压测下,最容易看出内存泄露的问题
JVM参数调优
Jvm常用参数
---------------------------------------
堆内存 = 年轻代+老年代
年轻代 = Eden+Survivor
Survivor = From Space+To Space
---------------------------------------
年轻代 = Eden+From Space+To Space
堆内存=Eden+From Space+To Space+老年代
====================================
-Xms2048m,初始堆大小,建议<物理内存的1/4,默认值为物理内存的1/64
-Xmx2048m,最大堆大小,建议与-Xms保持一致,默认值为物理内存的1/4
-Xmn512m,新生代大小,建议不超过堆内存的1/2
-Xss256k,线程堆栈大小,建议256k
-XX:PermSize=256m,永久代初始值,默认值为物理内存的1/64
-XX:MaxPermSize=256m,永久代最大值,默认值为物理内存的1/4
-XX:SurvivorRatio=8:年轻带中Eden区和Survivor区的比例,默认为8:1,即Eden(8),From Space(1),ToSpace(1)
-XX:MaxTenuringThreshold=15:晋升到老年代的对象年龄,每个对象坚持过一次MinorGC后对象年龄+1,默认值是15,年龄超过15进入到老年代,该参数在串行GC时有效
-XX:PretenureSizeThreshold=3145728:单位字节,只对Serial和ParNew两款收集器有效,新生代采用Parallel Scavenge GC时无效,大于这个值的对象直接在老年代进行分配
非稳定参数,使用方式主要有以下三种:
1,-XX +<option>:开启option参数
2,-XX -<option>:关闭option参数
3,-XX <option>=<value>:将option参数的值设置为value
client模式,Jvm默认垃圾收集器
UseSerialGC:新生代采用Serial收集器,老年代采用Serial Old收集器
server模式,Jvm默认垃圾回收期
UseParallelGc:新生代采用Parallel Scavenge收集器,吞吐量优先的收集器,老年代采用Serial Old收集器
-XX:+UseConcMarkSweepGC:默认关闭,ParNew+CMS+Serial Old,当CMS收集器出现ConcurrentModeFailure错误(Jvm预留空间不足以容纳程序使用),采用后备收集器Serial Old
CMS相关参数
-XX:CMSInitiatingOccupancyFraction=80:CMS收集器在老年代空间被使用多少时触发FullGC,默认为92,建议80左右
-XX:+UseCMSCompactAtFullCollection:CMS收集器在FullGC时开启内存碎片的压缩,默认关闭
-XX:CMSFullGCsBeforeCompaction=8:执行多少次不压缩FullGC后,进行一次压缩,默认是0(代表每次FullGC都进行压缩)
-XX:+UseCMSInitiatingOccupancyOnly:使用手动定义初始化定义开始,禁止hostspot自行触发CMS GC
-XX:ParallelGCThreads=8:并行收集器的线程数,此值最好配置与处理器数目相等 同样适用于CMS
日志参数:
-XX:+HeapDumpOnOutOfMemoryError:当发生内存溢出时,进行堆内存dump,一般把这个打开
-XX:+PrintGCDetails:打印GC的详细信息
======================================================================
企业实际配置
-server -Xms1028m -Xmx1028m -XX:PermSize=256m -XX:MaxPermSize=256m -Xmn512m -XX:MaxDirectMemorySize=1g -XX:SurvivorRatio=10
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSMaxAbortablePrecleanTime=5000
-XX:+CMSClassUnloadingEnabled
-XX:CMSInitiatingOccupancyFraction=80
-XX:+UseCMSInitiatingOccupancyOnly
-XX:ParallelGCThreads=8
-Xloggc:/home/admin/logs/gc.log
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/admin/logs/java.hprof
建议阅读《深入理解Java虚拟机》
性能测试三十六:内存溢出和JVM常见参数及JVM参数调优的更多相关文章
- 三十五.MySQL读写分离 MySQL多实例 、MySQL性能调优
1.实现MySQL读写分离 搭建一主一从结构 配置maxscale代理服务器 测试分离配置 1.1 搭建一主一从结构 192.168.4.51 主 192.168.4.52 从 测试OK 1. ...
- 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索
第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...
- Gradle 1.12用户指南翻译——第三十六章. Sonar Runner 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- NeHe OpenGL教程 第三十六课:从渲染到纹理
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- Java进阶(三十六)深入理解Java的接口和抽象类
Java进阶(三十六)深入理解Java的接口和抽象类 前言 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太 ...
- 第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础
第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础 在urllib中,我们一样可以使用xpath表达式进行信息提取,此时,你需要首先安装lxml模块 ...
- centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课
centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 ...
- “全栈2019”Java第三十六章:类
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 微信小程序把玩(三十六)Storage API
原文:微信小程序把玩(三十六)Storage API 其实这个存储在新建Demo的时候就已经用到了就是存储就是那个logs日志,数据存储主要分为同步和异步 异步存储方法: 存数据 wx.setStor ...
随机推荐
- Harbor镜像清理
目录 清理UI中的镜像 清理镜像释放空间 docker镜像仓库中镜像的清理,一直是个比较麻烦的事情.尤其是在测试环境当中,每天都会有大量的构建.由此会产生大量的历史镜像,而这些镜像,大多数都没有用. ...
- eclipse如何加入第三方jar包
1.项目右键选择“properties” 2.选Java Build Path 3.选Libraries 4.选add JRAS jar包下载平台:http://www.mvnrepository.c ...
- on条件与where条件的区别
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和where条件的区别如下: 1. on条件是在生成临时表时使用的条 ...
- mysql名词解释
什么是QPS? 单位时间内所处理的事务数 什么是TPS? 单位时间内所处理的查询数 响应时间 并发量 同时处理的查询请求的数量 什么是吞吐量?
- 原生js的ajax请求
传统方法的缺点: 传统的web交互是用户触发一个http请求服务器,然后服务器收到之后,在做出响应到用户,并且返回一个新的页面,,每当服务器处理客户端提交的请求时,客户都只能空闲等待,并且哪怕只是一次 ...
- python 小爬虫爬取博客文章初体验
最近学习 python 走火入魔,趁着热情继续初级体验一下下爬虫,以前用 java也写过,这里还是最初级的爬取html,都没有用html解析器,正则等...而且一直在循环效率肯定### 很低下 imp ...
- Css3实现常用的几种loading动画
css实现loading动画非常方便,也非常实用 第一种 <!DOCTYPE html> <html lang="en"> <head> < ...
- Keil4 几例异常解决办法
以下几个问题在Keil5上没有发现,不过因为下载的例子都是Keil4,强迫症让我用起了Keil4 错误一:main.c: Warning: C3910W: Old syntax, please use ...
- Prezento – 轻量、简单的 jQuery 幻灯片插件
Prezento 是一个超级简单的 jQuery 幻灯片插件.可以让你网页以新颖的交互方式呈现.另外,Prezento 支持响应式设计,配置项也很灵活,可以根据你需要的效果配置. 您可能感兴趣的相关文 ...
- 淘淘商城之springmvc前端控制器
一.web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=&qu ...