资讯专栏INFORMATION COLUMN

jvm调优

jemygraw / 2372人阅读

摘要:垃圾回收垃圾检测引用计数法和可达性分析算法。引用计数法给一个对象添加引用计数器,每当有个地方引用它,计数器就加,引用失效就减。通常会在老年代内存被占满时将会触发,回收整个堆内存。

基础知识

JVM - HotSpot内存布局(1.8之前版本)

1.8版本开始,持久区没有了,替代它的是metaspace。对于32位JVM,我通常不建议Java堆大小超过2Gb(-Xms2048m, -Xmx2048m),对于64位而言,我通常建议在每个JVM进程中Java堆大小的起始值设置在3GB或者4GB。典型的年轻代和老年代的比例是1:3或者33%。

垃圾回收

垃圾检测:引用计数法和可达性分析算法。
引用计数法:给一个对象添加引用计数器,每当有个地方引用它,计数器就加1,引用失效就减1。如果对象互相引用,那么就导致内存泄漏,所以这个方法已经被废弃。
可达性分析算法:以根集对象为起始点进行搜索,如果有对象不可达的话,即是垃圾对象。这里的根集一般包括java栈中引用的对象、方法区常量池中引用的对象和本地方法中引用的对象等。JVM在做垃圾回收的时候,会检查堆中的所有对象是否会被这些根集对象引用,不能够被引用的对象就会被垃圾收集器回收。
年轻代被分为3个部分,Enden区和两个Survivor区。当Eden区被对象填满时,就会执行Minor GC,并把所有存活下来的对象转移到其中一个survivor区。Minor GC同样会检查先前存活下来的对象,也把它们转移到这个survivor区。这样在一段时间内,总会有一个空的survivor区。经过多次GC周期后,仍然存活下来的对象会被转移到年老代内存空间。
年老代存放的都是生命周期较长的对象。通常会在老年代内存被占满时将会触发Full GC,回收整个堆内存。

常用工具:

jstack:查看每个线程的当前状态、调用栈、锁住或等待去锁定的资源,直接报告是否有线程死锁。

/root/jdk1.8.0_101/bin/jstack -l 6126

jmap:打印出java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。

jmap -dump:format=b,file=test.bin 6126

工具详细列表:http://blog.csdn.net/fenglibi...
JVM参数详解:http://0opslab.com/2016/01/16...

错误排查:

常见场景:CPU狂飙,通过ps -o pcpu,pid,tid找出是哪些线程在高频率的使用CPU,然后使用jstack命令找出这些线程,如果是普通线程,它的call stack直接反映出问题所在。如果是GC线程,通过gc日志可以看出GC线程在拼命GC,但是GC前后效果不明显,已用堆内存始终降不下来,其它线程会表现为alloc_enqueue_allocation_and_wait_for_gc的native_blocked阻塞状态,此时用jmap命令dump堆内存情况,使用eclipse MAT工具找出问题所在。
很多时候性能异常表现为偶然性,就是在不定的时间出现问题,此时通过给jvm加启动参数来生成转储文件,然后事后分析。-verbose:gc -Xloggc:xxx.txt生成gc日志,-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=yyy.txt在OOM出现后自动生成了堆转储文件,据此可分析堆和线程的情况。

内存溢出out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。memory leak会最终会导致out of memory!
以下为常见的内存错误:

java.lang.OutOfMemoryError: Java heap space 堆空间被占满
java.lang.OutOfMemoryError: PermGen space 持久代被占满(1.8之前版本)
java.lang.StackOverflowError 线程栈溢出
Fatal: Stack size too small 线程local area满
java.lang.OutOfMemoryError: unable to create new native thread 系统内存被占满

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66996.html

相关文章

  • 面试官问我JVM调优,我忍不住了!

    面试官:今天要不来聊聊JVM调优相关的吧?面试官:你曾经在生产环境下有过调优JVM的经历吗?候选者:没有面试官:...候选者:嗯...是这样的,我们一般优化系统的思路是这样的候选者:1. 一般来说关系型数据库是先到瓶颈,首先排查是否为数据库的问题候选者:(这个过程中就需要评估自己建的索引是否合理、是否需要引入分布式缓存、是否需要分库分表等等)候选者:2. 然后,我们会考虑是否需要扩容(横向和纵向都...

    不知名网友 评论0 收藏0
  • JVM体系结构与GC调优(二)

    摘要:在设计堆的大小时。设计为比更大的数前提是内存允许。这样既可以降低堆调整的频率,还可以提高系统的负载能力新生代调优大小增大区。因为时间跟存活对象成正比新生代调优晋升尽可能让对象停留在中。 jvm支持的垃圾收集器组合 showImg(https://segmentfault.com/img/bVbbcTv?w=1101&h=351); 组合选择的标准 吞吐量=应用运行时间/总时间 关...

    DirtyMind 评论0 收藏0
  • jvm调优

    摘要:一内存调优主要的目的是减小的频率和的次数。调优工具之主要用来输出中运行的进程状态信息。调优工具之和用来查看堆内存使用状况,一般结合使用。 一、jvm内存调优 主要的...

    snowLu 评论0 收藏0
  • JVM调优之经验

    摘要:内存设置现在线上业务系统基本物理内存都是够用的,不过物尽其用,我们调优就是争取让每空间都发挥出最大的作用。区总内存减去一个区的大小不宜过大,否则可能把物理内存耗光。 在生产系统中,高吞吐和低延迟一直都是JVM调优的最终目标,但这两者恰恰又是相悖的,鱼和熊掌不可兼得,所以在调优之前要清楚舍谁而取谁。一般计算任务和组件服务会偏向高吞吐,而web展示则偏向低延迟才会带来更好的用户体验。 本文...

    worldligang 评论0 收藏0
  • 记一次JVM调优

    摘要:现象登入生产环境,使用命令因为这时候并没有打的,所以只能观察现象。其他的可以根据这个类推,是内纯的占用量。 前言 我们的游戏上线之初,经常有玩家反馈卡,或者有网络延迟等现象,造成用户流失等现象,这时候我就想到是不是可能是之前的jvm配置有问题,或者存在内存泄露等问题。 现象 登入生产环境,使用命令,因为这时候并没有打gc的log,所以只能观察现象。 jstat -gcutil 270...

    sugarmo 评论0 收藏0
  • Java性能调优概述

    摘要:性能调优概述性能优化有风险和弊端,性能调优必须有明确的目标,不要为了调优而调优盲目调优,风险远大于收益程序性能的主要表现点执行速度程序的反映是否迅速,响应时间是否足够短内存分配内存分配是否合理,是否过多地消耗内存或者存在内存泄漏启动时间程序 [TOC] Java性能调优概述 性能优化有风险和弊端,性能调优必须有明确的目标,不要为了调优而调优!!!盲目调优,风险远大于收益!!! 程序性...

    ad6623 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<