堆内存溢出:

此种溢出,加内存只能缓解问题,不能根除问题,需优化代码
堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,就会出现内存溢出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参数调优的更多相关文章

  1. 三十五.MySQL读写分离 MySQL多实例 、MySQL性能调优

    1.实现MySQL读写分离 搭建一主一从结构 配置maxscale代理服务器 测试分离配置   1.1 搭建一主一从结构 192.168.4.51 主 192.168.4.52 从 测试OK   1. ...

  2. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  3. Gradle 1.12用户指南翻译——第三十六章. Sonar Runner 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  4. NeHe OpenGL教程 第三十六课:从渲染到纹理

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. Java进阶(三十六)深入理解Java的接口和抽象类

    Java进阶(三十六)深入理解Java的接口和抽象类 前言 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太 ...

  6. 第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础

    第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础 在urllib中,我们一样可以使用xpath表达式进行信息提取,此时,你需要首先安装lxml模块 ...

  7. centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课

    centos  shell脚本编程2 if 判断  case判断   shell脚本中的循环  for   while   shell中的函数  break  continue  test 命令   ...

  8. “全栈2019”Java第三十六章:类

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. 微信小程序把玩(三十六)Storage API

    原文:微信小程序把玩(三十六)Storage API 其实这个存储在新建Demo的时候就已经用到了就是存储就是那个logs日志,数据存储主要分为同步和异步 异步存储方法: 存数据 wx.setStor ...

随机推荐

  1. P4994 终于结束的起点

    P4994 终于结束的起点 现在,给你一个模数 M,请你求出最小的 n > 0,使得 \(\mathrm{fib}(n) \bmod M = 0, \mathrm{fib}(n + 1) \bm ...

  2. Spring_bean的实例化时机

    前言:创建Java对象 public class User { private String name; private Integer age; public User() { System.out ...

  3. mysql -- 动态获取结果集(重点)

    注意:语句传值的时候必须是带有@符号的参数,不能是自己的局部变量,一个@叫用户变量,两个@叫做全局变量.用户变量:当前用户的‘’全局变量‘’,用户状态存在时就存在,用户退出时消失. 初始版 delim ...

  4. 关于Springboot打包错误的问题 | Failed to execute goal org.springframework.boot:spring-boot-maven-plugin

    最近在使用spring-boot整合多模块,但是在父pom中打包maven install时总会报错:Failed to execute goal org.springframework.boot:s ...

  5. BigDecimal最基础用法【转】

    BigDecimal最基础用法 用字符串生成的BigDecimal是不会丢精度的. 简单除法. public class DemoBigDecimal { public static void mai ...

  6. C#星夜拾遗之delegate示例

    概念 delegate即委托.如果你使用过C++或者js中的回调函数,你会更容易明白一些.在异步操作中常常使用回调函数,例如在Ajax中,当HttpRequest执行异步请求时,就需要有一个状态改变时 ...

  7. winform,WPF 释放内存垃圾,减少资源占用方法

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]        public static extern boo ...

  8. 20155302 2016-2017-2 《Java程序设计》第九周学习总结

    20155302 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 基本数据库操作相关的JDBC接口或类是位于java.sql包中.在程序中要取得数据库联机,我 ...

  9. The provider is not compatible with the version of Oracle client

    保留下安装文件夹里的所有文件.然后把我那个很小应用软件(需要访问远程的oracle数据库)放在这个文件夹里.删除一下直接感觉无用的文件,先抽取可 能用不着的文件,保留放在另一个备用的文件夹里,然后运行 ...

  10. Linux - svn 操作

    --force # 强制覆盖 /usr/bin/svn --username user --password passwd co $Code ${SvnPath}src/ # 检出整个项目 /usr/ ...