JVM与性能调优

2020-03-24  本文已影响0人  crossyf

性能测试

在了解性能调优之前,首先得知道什么是性能测试,我们的程序怎样的性能表现才需要进行性能调优

一、性能测试概念

1.概念

用最低的资源换取最高的处理能力和低的响应时间在一定环境下做性能需求

2.问题
3.指标:

二、性能测试的标准

1.Tpc

给一个标准的业务,比较完成业务的能力

2.Spec

物理处理能力,比较固定业务换算的指标

三、性能测试的难点

1.用户层面

用户总希望在最小的代价下换回最大的收益

2.代码层面

项目一旦确定了架构,其性能也就确定了(开发者不遵守规范体系进行开发)

四、如何进行性能测试

1.模拟用户请求

模拟客户端对服务端的多线程调用,使用Testng、jemeter等工具模拟高并发

2.性能测试工具的要求

监控负载可以计算出响应时间和吞吐量

监控资源的工具

五、性能测试模型

响应时间随着负载的上升先稳定后上升,并且越来越快

TPS随着负载的上升先到峰值,后稳定,然后下降

TPS(Transction per second) 每秒处理请求的能力,从发起一次请求到服务器做出响应的过程

QPS(Query per second)每秒查询的次数,一般针对一个特定的查询,服务器在一秒中所处理的流量

TPS可以认为是一种特殊的QPS

JVM相关概念

一、JVM是什么

jvm(java virtual machine) java虚拟机,是保证java程序能够在不同的操作系统上正常运行的基础。write once run everywhere

JRE(Java Runtime Envirment) java运行环境,JRE中包含JVM

JDK通常我们在开发java项目所安装的都是JDK,它包含了java类库以及JRE

Java程序在运行的时候,首先将java文件编译成class文件,JVM就负责将class文件解析成不同的操作系统所能理解的字节码

二、为什么要学习JVM

Java开发中,不需要管理对象的销毁,JVM已经帮我们处理好了,虽然在大多数情况下,我们不需要对JVM进行任何操作,程序也能正常运行,但是如果我们能够了解类是如何加载的,我们编写的java对象、方法是如何在JVM中运行的,对象是如何进行回收的,程序出现OOM问题后我们该怎么办,那我们能开发一个更健壮的系统

三、JVM的具体构成与原理

1.JVM运行时数据区
image.png

先分析进程共享的区域

在分析线程共享的区域

2.类加载

想要更好的理解JVM运行时数据区,必须了解这些数据是怎么加载到JVM中的。下面就介绍一下java中类加载的过程。

java类的加载主要分为3个步骤:加载连接和初始化,而连接又分为三个步骤:验证准备解析。具体来看一下每一个过程都做了那些事情。

符号引用:以一组符号来描述所引用的对象,可以是任何形式的字面量,只要在解析的时候能够根据这个字面量无歧义的定位到目标即可,能根据这个字符串定位到指定的数据,比如java/lang/String

直接引用:直接指向目标的指针、相对偏移量或者是一个间接定位的句柄

理解

这里简单分析一下类加载之后,具体与JVM之间的关系以及JVM各个运行时数据区的联系:

3.GC回收

JVM内存模型

先来看一下JVM内存模型的图

image.png

JDK1.8中内存模型主要有一下几个部分,简单说明一下每个部分

垃圾回收算法

首先先介绍一下,JVM如何判断哪个对象是否需要回收,这里有两种算法,一个是引用计数法,一个是可达性算法

JVM中使用的可达性算法,那么有哪些对象可以作为GCRoot呢?

方法区中的对象是随着JVM进程的存在而存在的,他不会被回收,虚拟机栈和本地方法栈的变量是当前正在执行的方法,变量也不会被回收,所以他们可以作为GCRoot

1.标记清除算法

找出内存中需要回收的对象,并标记出来,然后清除他们。缺点:会造成内存不连续

2.标记整理算法

找出内存中需要回收的对象,并标记出来,然后把存活的对象向一边移动,然后清空另一边。缺点:

3.复制回收算法

将内存区域分为两个部分,每次只使用一块,当一块使用完了之后,将不需要回收的对象复制到另一块内存中。缺点:内存利用率低且如果有大量对象存活的时候,复制会消耗很多资源。

垃圾回收器

image.png
1.Serial/SerialOld垃圾收集器

单线程收集器,回收垃圾的时候会触发STW。新生代使用复制回收算法,老年代使用标记整理算法。

优点:简单高效。

缺点GC会暂停用户线程。

使用场景:单核CPU

2.ParNew垃圾收集器

多线程收集器,回收垃圾的时候会触发STW。新生代使用,采用复制回收算法。

优点:多CPU情况下,比Serial效率高。

缺点:会触发STW,单核CPU效率低。

使用场景Server模式下首选的新生代收集器。

3.Parallel Scavenge /Parallel Old垃圾收集器

ParNew一样是多线程收集器,但是它更注重吞吐量(运行用户代码的时间 / (运行用户代码的时间 + 垃圾回收时间))

新生代使用复制回收算法,老年代使用标记整理算法

4.CMS(Concurrent Mark Sweep)垃圾收集器

CMS是以获取最短回收停顿时间为目标的收集器 采用标记清除算法,真个步骤分为:

整个过程中,并发标记和并发清除可以和用户线程一起执行,降低了回收停顿的时间。

优点:并发收集,低停顿

缺点:产生大量的空间碎片,并发阶段会降低吞吐量

5.G1垃圾收集器

JDK7中开始使用,新生代和老年代使用同一个垃圾回收器。使用该垃圾收集器的时候,Java内存布局和其他收集器有很大的区别,它将整个Java堆划分为多个大小相等的独立区域(Region),新生代和老年代不再是物理隔离了,他们都是一部分Region

其过程可一分为下面几步:

总结:

上面所列举的垃圾收集器可以进行简要分类

image.png

四、如何对JVM进行调优

1.常用参数

在上面已经介绍了有关JVM的内存结构以及垃圾回收等相关的知识,那么对于我们开发者来说,如何去设置这些参数呢?下面的表格里,我列出了应该算是比较常用的一些命令。根据这些命令,我们可以很轻松的在IDE或者Tomcat中去配置这些参数。

image.png

2.常用命令

常用的查看JVM相关数据的命令有以下几个:

image.png image.png image.png image.png

3.常用工具

image.png image.png

那么当我们的项目出现OutOfMemeryError或者StackOfFlowError等错误的时候如何定位到问题呢?

得到hprof文件后我们需要借助一些工具来进行分析,这里推荐Eclipse Memory Analyzer工具(下载地址),安装好之后直接open file打开hprof后就会自动对其进行分析。

image.png

可以看到这里提供了很多的工具,你可以具体的查看来分析可能的问题。

4.总结

对于JVM的调优,没有一个确定的办法,只能根据具体的问题做出具体的分析。但是只要你对JVM内存模型、垃圾收集等具体的原理了解清楚,当出现问题的时候,你就知道该从哪里下手,如何能快速的定位到问题。

image.png
上一篇 下一篇

猜你喜欢

热点阅读