精华内容
下载资源
问答
  • Java 应用性能的瓶颈点非常多,比如磁盘、内存、网络 I/O 等系统因素,Java 应用代码,JVM GC,数据库,缓存等。笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层、数据库层、框架层、JVM 层
  • java性能调优实战学习笔记

    千次阅读 2020-05-28 00:38:03
    这是极客时间专栏《java性能调优实战》的部分学习笔记,个人感觉这个专栏内容不深,适合初学者,我只看了编程性能调优和数据库性能调优两块,其他的暂时不打算看了,后续有时间再看吧 文章目录如何制定性能调优标准...

    这是极客时间专栏《java性能调优实战》的部分学习笔记,个人感觉这个专栏内容不深,适合初学者,我只看了编程性能调优和数据库性能调优两块,其他的暂时不打算看了,后续有时间再看吧
    有任何问题可在我个人博客留言,或者直接在此处留言即可

    如何制定性能调优标准

    有哪些参考因素可以体现系统的性能?

    在我们了解性能指标之前,我们先来了解下哪些计算机资源会成为系统的性能瓶颈。

    CPU 、内存、磁盘IO、网络、异常、数据库、锁竞争

    • CPU:有的应用需要大量计算,他们会长时间、不间断地占用 CPU 资源,导致其他资源无法争夺到 CPU 而响应缓慢,从而带来系统性能问题。例如,代码递归导致的无限循环,正则表达式引起的回溯,JVM 频繁的 FULL GC,以及多线程编程造成的大量上下文切换等,这些都有可能导致 CPU 资源繁忙。
    • 内存:Java 程序一般通过 JVM 对内存进行分配管理,主要是用 JVM 中的堆内存来存储 Java 创建的对象。系统堆内存的读写速度非常快,所以基本不存在读写性能瓶颈。但是由于内存成本要比磁盘高,相比磁盘,内存的存储空间又非常有限。所以当内存空间被占满,对象无法回收时,就会导致内存溢出、内存泄露等问题。
    • 磁盘 I/O:磁盘相比内存来说,存储空间要大很多,但磁盘 I/O 读写的速度要比内存慢,虽然目前引入的 SSD 固态硬盘已经有所优化,但仍然无法与内存的读写速度相提并论。
    • 网络:网络对于系统性能来说,也起着至关重要的作用。如果你购买过云服务,一定经历过,选择网络带宽大小这一环节。带宽过低的话,对于传输数据比较大,或者是并发量比较大的系统,网络就很容易成为性能瓶颈。
    • 异常:Java 应用中,抛出异常需要构建异常栈,对异常进行捕获和处理,这个过程非常消耗系统性能。如果在高并发的情况下引发异常,持续地进行异常处理,那么系统的性能就会明显地受到影响。
    • 数据库:大部分系统都会用到数据库,而数据库的操作往往是涉及到磁盘 I/O 的读写。大量的数据库读写操作,会导致磁盘 I/O 性能瓶颈,进而导致数据库操作的延迟性。对于有大量数据库读写操作的系统来说,数据库的性能优化是整个系统的核心。
    • 锁竞争:在并发编程中,我们经常会需要多个线程,共享读写操作同一个资源,这个时候为了保持数据的原子性(即保证这个共享资源在一个线程写的时候,不被另一个线程修改),我们就会用到锁。锁的使用可能会带来上下文切换,从而给系统带来性能开销。JDK1.6 之后,Java 为了降低锁竞争带来的上下文切换,对 JVM 内部锁已经做了多次优化,例如,新增了偏向锁、自旋锁、轻量级锁、锁粗化、锁消除等。而如何合理地使用锁资源,优化锁资源,就需要你了解更多的操作系统知识、Java 多线程编程基础,积累项目经验,并结合实际场景去处理相关问题。

    可以用下面几个指标,来衡量一般系统的性能 :

    响应时间

    • 数据库响应时间:数据库操作所消耗的时间,往往是整个请求链中最耗时的;
    • 服务端响应时间:服务端包括 Nginx 分发的请求所消耗的时间以及服务端程序执行所消耗的时间;
    • 网络响应时间:这是网络传输时,网络硬件需要对传输的请求进行解析等操作所消耗的时间;
    • 客户端响应时间:对于普通的 Web、App 客户端来说,消耗时间是可以忽略不计的,但如果你的客户端嵌入了大量的逻辑处理,消耗的时间就有可能变长,从而成为系统的瓶颈。

    吞吐量

    在测试中,我们往往会比较注重系统接口的 TPS(每秒事务处理量),因为 TPS 体现了接口的性能,TPS 越大,性能越好。在系统中,我们也可以把吞吐量自下而上地分为两种:磁盘吞吐量和网络吞吐量。

    我们先来看磁盘吞吐量,磁盘性能有两个关键衡量指标。

    一种是IOPS(Input/Output Per Second),即每秒的输入输出量(或读写次数),这种是指单位时间内系统能处理的 I/O 请求数量,I/O 请求通常为读或写数据操作请求,关注的是随机读写性能。适应于随机读写频繁的应用,如小文件存储(图片)、OLTP 数据库、邮件服务器。

    另一种是数据吞吐量,这种是指单位时间内可以成功传输的数据量。对于大量顺序读写频繁的应用,传输大量连续数据,例如,电视台的视频编辑、视频点播 VOD(Video On Demand),数据吞吐量则是关键衡量指标。

    网络吞吐量这个是指网络传输时没有帧丢失的情况下,设备能够接受的最大数据速率。网络吞吐量不仅仅跟带宽有关系,还跟 CPU 的处理能力、网卡、防火墙、外部接口以及 I/O 等紧密关联。而吞吐量的大小主要由网卡的处理能力、内部程序算法以及带宽大小决定。

    计算机资源分配使用率

    通常由 CPU 占用率、内存使用率、磁盘 I/O、网络 I/O 来表示资源使用率。这几个参数好比一个木桶,如果其中任何一块木板出现短板,任何一项分配不合理,对整个系统性能的影响都是毁灭性的。

    负载承受能力

    当系统压力上升时,你可以观察,系统响应时间的上升曲线是否平缓。这项指标能直观地反馈给你,系统所能承受的负载压力极限。例如,当你对系统进行压测时,系统的响应时间会随着系统并发数的增加而延长,直到系统无法处理这么多请求,抛出大量错误时,就到了极限。

    如何制定性能调优策略

    img-aNHai3Bg-1590596845194

    慎重使用正则表达式

    正则表达式引擎

    正则表达式是一个用正则符号写出的公式,程序对这个公式进行语法分析,建立一个语法分析树,再根据这个分析树结合正则表达式的引擎生成执行程序(这个执行程序我们把它称作状态机,也叫状态自动机),用于字符匹配。

    而这里的正则表达式引擎就是一套核心算法,用于建立状态机。

    目前实现正则表达式引擎的方式有两种:DFA 自动机(Deterministic Final Automaton 确定有限状态自动机)和 NFA 自动机(Non deterministic Finite Automaton 非确定有限状态自动机)。

    对比来看,构造 DFA 自动机的代价远大于 NFA 自动机,但 DFA 自动机的执行效率高于 NFA 自动机。

    假设一个字符串的长度是 n,如果用 DFA 自动机作为正则表达式引擎,则匹配的时间复杂度为 O(n);如果用 NFA 自动机作为正则表达式引擎,由于 NFA 自动机在匹配过程中存在大量的分支和回溯,假设 NFA 的状态数为 s,则该匹配算法的时间复杂度为 O(ns)。

    NFA 自动机的优势是支持更多功能。例如,捕获 group、环视、占有优先量词等高级功能。这些功能都是基于子表达式独立进行匹配,因此在编程语言里,使用的正则表达式库都是基于 NFA 实现的。

    用 NFA 自动机实现的比较复杂的正则表达式,在匹配过程中经常会引起回溯问题。大量的回溯会长时间地占用 CPU,从而带来系统性能开销。

    举例说明 :

    text=“abbc”

    regex=“ab{1,3}c”

    这个例子,匹配目的比较简单。匹配以 a 开头,以 c 结尾,中间有 1-3 个 b 字符的字符串。NFA 自动机对其解析的过程是这样的:首先,读取正则表达式第一个匹配符 a 和字符串第一个字符 a 进行比较,a 对 a,匹配。

    然后,读取正则表达式第二个匹配符 b{1,3} 和字符串的第二个字符 b 进行比较,匹配。但因为 b{1,3} 表示 1-3 个 b 字符串,NFA 自动机又具有贪婪特性,所以此时不会继续读取正则表达式的下一个匹配符,而是依旧使用 b{1,3} 和字符串的第三个字符 b 进行比较,结果还是匹配。

    接着继续使用 b{1,3} 和字符串的第四个字符 c 进行比较,发现不匹配了,此时就会发生回溯,已经读取的字符串第四个字符 c 将被吐出去,指针回到第三个字符 b 的位置。
    img-4Y4zrUZt-1590596845200

    那么发生回溯以后,匹配过程怎么继续呢?程序会读取正则表达式的下一个匹配符 c,和字符串中的第四个字符 c 进行比较,结果匹配,结束。

    如何减少回溯问题?

    既然回溯会给系统带来性能开销,那我们如何应对呢?如果你有仔细看上面那个案例的话,你会发现 NFA 自动机的贪婪特性就是导火索,这和正则表达式的匹配模式息息相关。

    **贪婪模式(Greedy)**顾名思义,就是在数量匹配中,如果单独使用+、 ? 、* 或{min,max} 等量词,正则表达式会匹配尽可能多的内容。例如,上边那个例子:

    **懒惰模式(Reluctant)**在该模式下,正则表达式会尽可能少地重复匹配字符。如果匹配成功,它会继续匹配剩余的字符串。

    例如,在上面例子的字符后面加一个“?”,就可以开启懒惰模式。

    text=“abc”

    regex=“ab{1,3}?c”

    匹配结果是“abc”,该模式下 NFA 自动机首先选择最小的匹配范围,即匹配 1 个 b 字符,因此就避免了回溯问题。

    懒惰模式是无法完全避免回溯的,我们再通过一个例子来了解下懒惰模式在什么情况下会发生回溯问题。

    text=“abbc”

    regex=“ab{1,3}?c”

    以上匹配结果依然是成功的,这又是为什么呢?我们可以通过懒惰模式的匹配过程来了解下原因。

    首先,读取正则表达式第一个匹配符 a 和字符串第一个字符 a 进行比较,a 对 a,匹配。然后,读取正则表达式第二个匹配符 b{1,3} 和字符串的第二个字符 b 进行比较,匹配。

    其次,由于懒惰模式下,正则表达式会尽可能少地重复匹配字符,匹配字符串中的下一个匹配字符 b 不会继续与 b{1,3}进行匹配,转而匹配正则表达式中的下一个字符 c。

    此时你会发现匹配字符 b 与正则表达式中的字符 c 是不匹配的,这个时候会发生一次回溯,这次的回溯与贪婪模式中的回溯刚好相反,懒惰模式的回溯是回溯正则表达式中一个匹配字符,与上一个字符再进行匹配。如果匹配,则将匹配字符串的下一个字符和正则表达式的下一个字符。

    独占模式(Possessive)

    同贪婪模式一样,独占模式一样会最大限度地匹配更多内容;不同的是,在独占模式下,匹配失败就会结束匹配,不会发生回溯问题。

    还是上边的例子,在字符后面加一个“+”,就可以开启独占模式。

    text=“abbc”

    regex=“ab{1,3}+bc”

    结果是不匹配,结束匹配,不会发生回溯问题。

    同样,独占模式也不能避免回溯的发生,我们再拿最开始的这个例子来分析下:

    text=“abbc”

    regex=“ab{1,3}+c”

    结果是匹配的,这是因为与贪婪模式一样,独占模式一样会最大限度地匹配更多内容,即匹配完所有的 b 之后,再去匹配 c,则匹配成功了。

    在很多情况下使用懒惰模式和独占模式可以减少回溯的发生。

    正则表达式的优化

    1. 少用贪婪模式,多用独占模式

      贪婪模式会引起回溯问题,我们可以使用独占模式来避免回溯。前面详解过了,这里我就不再解释了。

    2. 减少分支选择

      分支选择类型“(X|Y|Z)”的正则表达式会降低性能,我们在开发的时候要尽量减少使用。如果一定要用,我们可以通过以下几种方式来优化:

      首先,我们需要考虑选择的顺序,将比较常用的选择项放在前面,使它们可以较快地被匹配;

      其次,我们可以尝试提取共用模式,例如,将“(abcd|abef)”替换为“ab(cd|ef)”,后者匹配速度较快,因为 NFA 自动机会尝试匹配 ab,如果没有找到,就不会再尝试任何选项;

      最后,如果是简单的分支选择类型,我们可以用三次 index 代替“(X|Y|Z)”,如果测试的话,你就会发现三次 index 的效率要比“(X|Y|Z)”高出一些。

    3. 减少捕获嵌套

      捕获组是指把正则表达式中,子表达式匹配的内容保存到以数字编号或显式命名的数组中,方便后面引用。一般一个 () 就是一个捕获组,捕获组可以进行嵌套。

      非捕获组则是指参与匹配却不进行分组编号的捕获组,其表达式一般由(?:exp)组成。

      在正则表达式中,每个捕获组都有一个编号,编号 0 代表整个匹配到的内容。我们可以看下面的例子:

      public static void main( String[] args )
      {
        String text = "<input high=\"20\" weight=\"70\">test</input>";
        String reg="(<input.*?>)(.*?)(</input>)";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(text);
        while(m.find()) {
          System.out.println(m.group(0));//整个匹配到的内容
          System.out.println(m.group(1));//(<input.*?>)
          System.out.println(m.group(2));//(.*?)
          System.out.println(m.group(3));//(</input>)
        }
      }
      

      运行结果:

      <input high=\"20\" weight=\"70\">test</input>
      <input high=\"20\" weight=\"70\">
      test
      </input>
      

      如果你并不需要获取某一个分组内的文本,那么就使用非捕获分组。例如,使用“(?:X)”代替“(X)”,我们再看下面的例子:

      public static void main( String[] args )
      {
        String text = "<input high=\"20\" weight=\"70\">test</input>";
        String reg="(?:<input.*?>)(.*?)(?:</input>)";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(text);
        while(m.find()) {
          System.out.println(m.group(0));//整个匹配到的内容
          System.out.println(m.group(1));//(.*?)
        }
      }
      

      运行结果:

      <input high=\"20\" weight=\"70\">test</input>
      test
      

      综上可知:减少不需要获取的分组,可以提高正则表达式的性能。

    正则表达式虽然小,却有着强大的匹配功能。我们经常用到它,比如,注册页面手机号或邮箱的校验。

    但很多时候,我们又会因为它小而忽略它的使用规则,测试用例中又没有覆盖到一些特殊用例,不乏上线就中招的情况发生。

    如果使用正则表达式能使你的代码简洁方便,那么在做好性能排查的前提下,可以去使用;如果不能,那么正则表达式能不用就不用,以此避免造成更多的性能问题。

    ArrayList和LinkedList

    我们在查看 ArrayList 的实现类源码时,你会发现对象数组 elementData 使用了 transient 修饰,我们知道 transient 关键字修饰该属性,则表示该属性不会被序列化,然而我们并没有看到文档中说明 ArrayList 不能被序列化,这是为什么?

    ArrayList 属性主要由数组长度 size、对象数组 elementData、初始化容量 default_capacity 等组成, 其中初始化容量默认大小为 10。

     //默认初始化容量
        private static final int DEFAULT_CAPACITY = 10;
        //对象数组
        transient Object[] elementData; 
        //数组长度
        private int size;
    

    从 ArrayList 属性来看,它没有被任何的多线程关键字修饰,但 elementData 被关键字 transient 修饰了。

    由于 ArrayList 的数组是基于动态扩增的,所以并不是所有被分配的内存空间都存储了数据。如果采用外部序列化法实现数组的序列化,会序列化整个数组。ArrayList 为了避免这些没有存储数据的内存空间被序列化,内部提供了两个私有方法 writeObject 以及 readObject 来自我完成序列化与反序列化,从而在序列化与反序列化数组时节省了空间和时间。

    因此使用 transient 修饰数组,是防止对象数组被其他外部方法序列化

    Stream如何提高遍历集合效率

    官方将 Stream 中的操作分为两大类:中间操作(Intermediate operations)和终结操作(Terminal operations)。中间操作只对操作进行了记录,即只会返回一个流,不会进行计算操作,而终结操作是实现了计算操作。

    中间操作又可以分为无状态(Stateless)与有状态(Stateful)操作,前者是指元素的处理不受之前元素的影响,后者是指该操作只有拿到所有元素之后才能继续下去。

    终结操作又可以分为短路(Short-circuiting)与非短路(Unshort-circuiting)操作,前者是指遇到某些符合条件的元素就可以得到最终结果,后者是指必须处理完所有元素才能得到最终结果。操作分类详情如下图所示:
    img-HJ6c83OJ-1590596845204

    我们通常还会将中间操作称为懒操作,也正是由这种懒操作结合终结操作、数据源构成的处理管道(Pipeline),实现了 Stream 的高效。

    在循环迭代次数较少的情况下,常规的迭代方式性能反而更好;在单核 CPU 服务器配置环境中,也是常规迭代方式更有优势;而在大数据循环迭代中,如果服务器是多核 CPU 的情况下,Stream 的并行迭代优势明显。所以我们在平时处理大数据的集合时,应该尽量考虑将应用部署在多核 CPU 环境下,并且使用 Stream 的并行迭代方式进行处理。

    Hashmap

    HashMap 扩容优化 :

    在 JDK1.7 中,HashMap 整个扩容过程就是分别取出数组元素,一般该元素是最后一个放入链表中的元素,然后遍历以该元素为头的单向链表元素,依据每个被遍历元素的 hash 值计算其在新数组中的下标,然后进行交换。这样的扩容方式会将原来哈希冲突的单向链表尾部变成扩容后单向链表的头部。

    而在 JDK 1.8 中,HashMap 对扩容操作做了优化。由于扩容数组的长度是 2 倍关系,所以对于假设初始 tableSize = 4 要扩容到 8 来说就是 0100 到 1000 的变化(左移一位就是 2 倍),在扩容中只用判断原来的 hash 值和左移动的一位(newtable 的值)按位与操作是 0 或 1 就行,0 的话索引不变,1 的话索引变成原索引加上扩容前数组。

    之所以能通过这种“与运算“来重新分配索引,是因为 hash 值本来就是随机的,而 hash 按位与上 newTable 得到的 0(扩容前的索引位置)和 1(扩容前索引位置加上扩容前数组长度的数值索引处)就是随机的,所以扩容的过程就能把之前哈希冲突的元素再随机分布到不同的索引中去。

    实际应用中,我们设置初始容量,一般得是 2 的整数次幂。你知道原因吗?

    1)通过将 Key 的 hash 值与 length-1 进行 & 运算,实现了当前 Key 的定位,2 的幂次方可以减少冲突(碰撞)的次数,提高 HashMap 查询效率;
    2)如果 length 为 2 的次幂,则 length-1 转化为二进制必定是 11111…… 的形式,在于 h 的二进制与操作效率会非常的快,而且空间不浪费;如果 length 不是 2 的次幂,比如 length 为 15,则 length-1 为 14,对应的二进制为 1110,在于 h 与操作,最后一位都为 0,而 0001,0011,0101,1001,1011,0111,1101 这几个位置永远都不能存放元素了,空间浪费相当大,更糟的是这种情况中,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了碰撞的几率,减慢了查询的效率!这样就会造成空间的浪费。

    MySQL调优之SQL语句:如何写出高性能SQL语句?

    慢 SQL 语句的几种常见诱因

    • 无索引、索引失效导致慢查询

    • 锁等待

    我们常用的存储引擎有 InnoDB 和 MyISAM,前者支持行锁和表锁,后者只支持表锁。

    如果数据库操作是基于表锁实现的,试想下,如果一张订单表在更新时,需要锁住整张表,那么其它大量数据库操作(包括查询)都将处于等待状态,这将严重影响到系统的并发性能。

    这时,InnoDB 存储引擎支持的行锁更适合高并发场景。但在使用 InnoDB 存储引擎时,我们要特别注意行锁升级为表锁的可能。在批量更新操作时,行锁就很可能会升级为表锁。

    MySQL 认为如果对一张表使用大量行锁,会导致事务执行效率下降,从而可能造成其它事务长时间锁等待和更多的锁冲突问题发生,致使性能严重下降,所以 MySQL 会将行锁升级为表锁。还有,行锁是基于索引加的锁,如果我们在更新操作时,条件索引失效,那么行锁也会升级为表锁。

    因此,基于表锁的数据库操作,会导致 SQL 阻塞等待,从而影响执行速度。在一些更新操作(insert\update\delete)大于或等于读操作的情况下,MySQL 不建议使用 MyISAM 存储引擎。

    除了锁升级之外,行锁相对表锁来说,虽然粒度更细,并发能力提升了,但也带来了新的问题,那就是死锁。因此,在使用行锁时,我们要注意避免死锁。关于死锁,我还会在第 35 讲中详解。

    • 不恰当的 SQL 语句

    优化 SQL 语句的步骤

    通常,我们在执行一条 SQL 语句时,要想知道这个 SQL 先后查询了哪些表,是否使用了索引,这些数据从哪里获取到,获取到数据遍历了多少行数据等等,我们可以通过 EXPLAIN 命令来查看这些执行信息。这些执行信息被统称为执行计划

    通过 EXPLAIN 分析 SQL 执行计划

    假设现在我们使用 EXPLAIN 命令查看当前 SQL 是否使用了索引,先通过 SQL EXPLAIN 导出相应的执行计划如下:
    img-josLIzGQ-1590596845205

    • id:每个执行计划都有一个 id,如果是一个联合查询,这里还将有多个 id。
    • select_type:表示 SELECT 查询类型,常见的有 SIMPLE(普通查询,即没有联合查询、子查询)、PRIMARY(主查询)、UNION(UNION 中后面的查询)、SUBQUERY(子查询)等。
    • table:当前执行计划查询的表,如果给表起别名了,则显示别名信息。
    • partitions:访问的分区表信息。
    • type:表示从表中查询到行所执行的方式,查询方式是 SQL 优化中一个很重要的指标,结果值从好到差依次是:system > const > eq_ref > ref > range > index > ALL

    system/const:表中只有一行数据匹配,此时根据索引查询一次就能找到对应的数据。
    img-Mhs3nURR-1590596845207

    eq_ref:使用唯一索引扫描,常见于多表连接中使用主键和唯一索引作为关联条件。
    img-MyBfZqNl-1590596845208

    ref:非唯一索引扫描,还可见于唯一索引最左原则匹配扫描。
    img-9bSj6Vgz-1590597247652
    range:索引范围扫描,比如,<,>,between等操作。
    img-BCzVZrbf-1590596845210
    index:索引全表扫描,此时遍历整个索引树。
    img-ykHfSi3W-1590596845211

    ALL:表示全表扫描,需要遍历全表来找到对应的行。

    possible_keys:可能使用到的索引。

    key:实际使用到的索引。

    key_len:当前使用的索引的长度。

    ref:关联 id 等信息。

    rows:查找到记录所扫描的行数。

    filtered:查找到所需记录占总扫描记录数的比例。

    Extra:额外的信息。

    通过 Show Profile 分析 SQL 执行性能

    上述通过 EXPLAIN 分析执行计划,仅仅是停留在分析 SQL 的外部的执行情况,如果我们想要深入到 MySQL 内核中,从执行线程的状态和时间来分析的话,这个时候我们就可以选择 Profile。

    Profile 除了可以分析执行线程的状态和时间,还支持进一步选择 ALL、CPU、MEMORY、BLOCK IO、CONTEXT SWITCHES等类型来查询 SQL 语句在不同系统资源上所消耗的时间。以下是相关命令的注释:

    SHOW PROFILE [type [, type] ... ]
    [FOR QUERY n]
    [LIMIT row_count [OFFSET offset]]
    
    type参数:
    | ALL:显示所有开销信息
    | BLOCK IO:阻塞的输入输出次数
    | CONTEXT SWITCHES:上下文切换相关开销信息
    | CPU:显示CPU的相关开销信息 
    | IPC:接收和发送消息的相关开销信息
    | MEMORY :显示内存相关的开销,目前无用
    | PAGE FAULTS :显示页面错误相关开销信息
    | SOURCE :列出相应操作对应的函数名及其在源码中的调用位置(行数) 
    | SWAPS:显示swap交换次数的相关开销信息
    

    可以通过 select @@have_profiling 查询是否支持profile功能

    Show Profiles 只显示最近发给服务器的 SQL 语句,默认情况下是记录最近已执行的 15 条记录,我们可以重新设置profiling_history_size增大该存储记录,最大值为 100。
    img-gxnQXHeJ-1590596845212

    获取到 Query_ID 之后,我们再通过 Show Profile for Query ID语句,就能够查看到对应 Query_ID 的 SQL 语句在执行过程中线程的每个状态所消耗的时间了:
    img-REtSwZot-1590596845213

    通过以上分析可知:SELECT COUNT(*) FROM order; SQL 语句在 Sending data 状态所消耗的时间最长,这是因为在该状态下,MySQL 线程开始读取数据并返回到客户端,此时有大量磁盘 I/O 操作。

    常用的 SQL 优化

    优化分页查询

    通常我们是使用 + 合适的 order by 来实现分页查询,这种实现方式在没有任何索引条件支持的情况下,需要做大量的文件排序操作(file sort),性能将会非常得糟糕。如果有对应的索引,通常刚开始的分页查询效率会比较理想,但越往后,分页查询的性能就越差。

    这是因为我们在使用 LIMIT 的时候,偏移量 M 在分页越靠后的时候,值就越大,数据库检索的数据也就越多。例如 LIMIT 10000,10 这样的查询,数据库需要查询 10010 条记录,最后返回 10 条记录。也就是说将会有 10000 条记录被查询出来没有被使用到。

    • 利用子查询优化分页查询

      以上分页查询的问题在于,我们查询获取的 10020 行数据结果都返回给我们了,我们能否先查询出所需要的 20 行数据中的最小 ID 值,然后通过偏移量返回所需要的 20 行数据给我们呢?我们可以通过索引覆盖扫描,使用子查询的方式来实现分页查询:

      select * from `demo`.`order` where id> (select id from `demo`.`order` order by order_no limit 10000, 1)  limit 20;
      

    img-O7cZC4Q1-1590596845214
    img-Q06b0iVn-1590596845216

    优化 SELECT COUNT(*)

    通常在没有任何查询条件下的 COUNT(*),MyISAM 的查询速度要明显快于 InnoDB。这是因为 MyISAM 存储引擎记录的是整个表的行数,在 COUNT(*) 查询操作时无需遍历表计算,直接获取该值即可。而在 InnoDB 存储引擎中就需要扫描表来统计具体的行数。而当带上 where 条件语句之后,MyISAM 跟 InnoDB 就没有区别了,它们都需要扫描表来进行行数的统计。

    如果对一张大表经常做 SELECT COUNT(*) 操作,这肯定是不明智的。那么我们该如何对大表的 COUNT() 进行优化呢?

    • 使用近似值

      有时候某些业务场景并不需要返回一个精确的 COUNT 值,此时我们可以使用近似值来代替。我们可以使用 EXPLAIN 对表进行估算,要知道,执行 EXPLAIN 并不会真正去执行查询,而是返回一个估算的近似值。

    • 增加汇总统计

      如果需要一个精确的 COUNT 值,我们可以额外新增一个汇总统计表或者缓存字段来统计需要的 COUNT 值,这种方式在新增和删除时有一定的成本,但却可以大大提升 COUNT() 的性能。

    我们可以打开慢 SQL 配置项,记录下都有哪些 SQL 超过了预期的最大执行时间。首先,我们可以通过以下命令行查询是否开启了记录慢 SQL 的功能,以及最大的执行时间是多少:

    Show variables like 'slow_query%';
    Show variables like 'long_query_time';
    

    如果没有开启,我们可以通过以下设置来开启:

    set global slow_query_log='ON'; //开启慢SQL日志
    set global slow_query_log_file='/var/lib/mysql/test-slow.log';//记录日志地址
    set global long_query_time=1;//最大执行时间
    

    思考题:

    假设有一张订单表 order,主要包含了主键订单编码 order_no、订单状态 status、提交时间 create_time 等列,并且创建了 status 列索引和 create_time 列索引。此时通过创建时间降序获取状态为 1 的订单编码,以下是具体实现代码:

    select order_no from order where status =1 order by create_time desc
    

    你知道其中的问题所在吗?我们又该如何优化?

    status和create_time单独建索引,在查询时只会遍历status索引对数据进行过滤,不会用到create_time列索引,将符合条件的数据返回到server层,在server对数据通过快排算法进行排序,Extra列会出现file sort;应该利用索引的有序性,在status和create_time列建立联合索引,这样根据status过滤后的数据就是按照create_time排好序的,避免在server层排序

    MySQL调优之事务:高并发场景下的数据库事务调优

    InnoDB 中的 RC 和 RR 隔离事务是基于多版本并发控制(MVCC)实现高性能事务。一旦数据被加上排他锁,其他事务将无法加入共享锁,且处于阻塞等待状态,如果一张表有大量的请求,这样的性能将是无法支持的。

    MVCC 对普通的 Select 不加锁,如果读取的数据正在执行 Delete 或 Update 操作,这时读取操作不会等待排它锁的释放,而是直接利用 MVCC 读取该行的数据快照(数据快照是指在该行的之前版本的数据,而数据快照的版本是基于 undo 实现的,undo 是用来做事务回滚的,记录了回滚的不同版本的行记录)。MVCC 避免了对数据重复加锁的过程,大大提高了读操作的性能。

    行锁的具体实现算法有三种:record lock、gap lock 以及 next-key lock。record lock 是专门对索引项加锁;gap lock 是对索引项之间的间隙加锁;next-key lock 则是前面两种的组合,对索引项以其之间的间隙加锁。

    只在可重复读或以上隔离级别下的特定操作才会取得 gap lock 或 next-key lock,在 Select 、Update 和 Delete 时,除了基于唯一索引的查询之外,其他索引查询时都会获取 gap lock 或 next-key lock,即锁住其扫描的范围。

    优化高并发事务

    • 结合业务场景,使用低级别事务隔离
    • 避免行锁升级表锁
    • 控制事务的大小,减少锁定的资源量和锁定时间长度

    MySQL调优之索引:索引的失效与优化

    覆盖索引优化查询

    假设我们只需要查询商品的名称、价格信息,我们有什么方式来避免回表呢?我们可以建立一个组合索引,即商品编码、名称、价格作为一个组合索引。如果索引中存在这些数据,查询将不会再次检索主键索引,从而避免回表。

    从辅助索引中查询得到记录,而不需要通过聚簇索引查询获得,MySQL 中将其称为覆盖索引。使用覆盖索引的好处很明显,我们不需要查询出包含整行记录的所有信息,因此可以减少大量的 I/O 操作。

    自增字段作主键优化查询

    InnoDB 创建主键索引默认为聚簇索引,数据被存放在了 B+ 树的叶子节点上。也就是说,同一个叶子节点内的各个数据是按主键顺序存放的,因此,每当有一条新的数据插入时,数据库会根据主键将其插入到对应的叶子节点中。

    如果我们使用自增主键,那么每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为不需要重新移动数据,因此这种插入数据的方法效率非常高。

    如果我们使用非自增主键,由于每次插入主键的索引值都是随机的,因此每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,这将不得不移动其它数据来满足新数据的插入,甚至需要从一个页面复制数据到另外一个页面,我们通常将这种情况称为页分裂。页分裂还有可能会造成大量的内存碎片,导致索引结构不紧凑,从而影响查询效率。

    因此,在使用 InnoDB 存储引擎时,如果没有特别的业务需求,建议使用自增字段作为主键。

    前缀索引优化

    前缀索引顾名思义就是使用某个字段中字符串的前几个字符建立索引,那我们为什么需要使用前缀来建立索引呢?我们知道,索引文件是存储在磁盘中的,而磁盘中最小分配单元是页,通常一个页的默认大小为 16KB,假设我们建立的索引的每个索引值大小为 2KB,则在一个页中,我们能记录 8 个索引值,假设我们有 8000 行记录,则需要 1000 个页来存储索引。如果我们使用该索引查询数据,可能需要遍历大量页,这显然会降低查询效率。减小索引字段大小,可以增加一个页中存储的索引项,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。不过,前缀索引是有一定的局限性的,例如 order by 就无法使用前缀索引,无法把前缀索引用作覆盖索引。

    防止索引失效

    在大多数情况下,我们习惯使用默认的 InnoDB 作为表存储引擎。在使用 InnoDB 作为存储引擎时,创建的索引默认为 B+ 树数据结构,如果是主键索引,则属于聚簇索引,非主键索引则属于辅助索引。基于主键查询可以直接获取到行信息,而基于辅助索引作为查询条件,则需要进行回表,然后再通过主键索引获取到数据。如果只是查询一列或少部分列的信息,我们可以基于覆盖索引来避免回表。覆盖索引只需要读取索引,且由于索引是顺序存储,对于范围或排序查询来说,可以极大地极少磁盘 I/O 操作。

    展开全文
  • 为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来。 仅当我在用Java编写的任务关键型服务器端财务应用程序中遇到严重的性能和...

    java必读书籍

    为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来。 仅当我在用Java编写的任务关键型服务器端财务应用程序中遇到严重的性能和可伸缩性问题时,我才意识到自己缺乏对性能测量,调试和查找瓶颈的知识,这是我的错误。 的确,当您真正需要它时,您将学习最多,但是那些时间并不是学习基础知识的最佳时间,实际上,这些时间是应用并纠正您的误解的时间。 这就是为什么我与所有Java程序员共享这些Java性能书籍 ,并建议他们花一些时间至少阅读一本完整的书籍。 顺便提一下,这些书除了我的5本必读之书之外,还适合Java程序员 。 请记住,有关性能调优的知识是高级Java开发人员的重要方面之一,可以使您与众不同。 自将Java引入20年前以来,它就一直因其速度慢和性能不足而受到批评。 今天,就本地语言的性能而言,我认为Java不会落后。 鉴于Java具有使用JIT(及时编译器)本地编译热代码的能力,它几乎可以与用C和C ++编写的本地应用程序相提并论,但是可以通过遵循最佳实践,避免常见的性能陷阱并使用最新工具来完成很多工作。和技术。 在本文中,我将介绍有关Java性能的五本一本不错的书,它们不仅会教您测量什么,如何测量,而且还将解释这些问题背后的基础知识和概念。 您不仅将了解运行Java应用程序的系统和JVM,还将学习如何使用Java API编写更快的代码。 因此,我们还等什么呢,让我们开始探索有关Java性能调优的书籍。

    1. Java Performance权威指南Scott Oaks

      Java_performance_the_definite_guide_Stock 一言以蔽之,这是当前有关Java性能优化的最佳书籍 。 造成这种情况的原因有很多,其中之一是,这是一本最新的书,涵盖了Java 7更新40。要学习性能调整,您应该了解工具,过程,选项,最重要的是避免常见的性能陷阱 。 本书在这一点上得分很高,它的章节介绍了Java性能工程师应该意识到的所有工具,包括Java 7u40中添加的工具,例如Flight Recorder和Java Mission Control。 它也有很好的章节介绍各种垃圾收集算法,例如并发标记扫描(CMS)和G1垃圾收集器。 您将学习它们在不同条件下如何工作,如何监视它们以及如何对其进行调整。 它还包括一整章有关堆分析和优化的内容。 这将教您一些常见的知识,例如如何用Java进行堆转储和直方图,然后介绍许多减少堆内存占用的方法 。 它还有一章介绍JDBC和JPA性能。 关键点在于,它告诉您如何选择适当的JDBC / JPA方法可能远远超过了SQL查询调整带来的收益。 同样,它有一章完整的章节介绍了有关多线程问题,陷阱和对性能的影响。 它包括高级主题,例如ForkJoinPool和Java 8 Streams。 它还基于同步和错误共享,调整JVM线程(例如线程堆栈大小),配置有偏锁,线程优先级和线程旋转的成本。 顺便说一下,到目前为止还没有介绍什么,本书中最喜欢的II是第12章。本章介绍了一些经典的Java核心调优技巧及其影响。 这包括缓冲的I / O,类加载,随机数生成,JNI,异常,字符串性能,日志记录,Java Collections API,Java 8 lambda和vs匿名类,最后是Java 8流和多个过滤器性能。 这实际上是我阅读的第一章,我爱上了它的内容和风格。 如果您想自己快速评估本书,建议您从本章开始。 它还基于Java EE性能,解释了XML和JSON解析以及对象序列化的可能问题。

    2. Java Performance by Binu John,查理·亨特(Charlie Hunt)

      Java性能 长期以来,这是我最喜欢的Java性能书,直到最近阅读Scott Oaks撰写的Java Performance The Definitive Guide。 这本书非常相似,就像从顶部取代它的那本书一样。 它的章节解释了如何进行性能测量,并解释了测量CPU,内存和IO所需的工具。 有关解释垃圾收集工作原理的章节,不同的GC算法(例如串行垃圾收集器与并行垃圾收集器,并发标记扫描收集器等)。Binu John和Charlie Hunt在如何构造实验以发现优化机会,解释结果并采取行动方面做得非常出色。有效的行动。 为了给您一些信誉并暗示您在本书中可以期望得到的结果,Charlie Hunt是Oracle的JVM性能首席工程师。 他负责改善HotSpot JVM和Java SE类库的性能。 他还参与了改善Oracle GlassFish和Oracle WebLogic Server的性能的工作,Binu John是Ning,Inc.的高级性能工程师,他致力于改善Ning平台的性能和可伸缩性,以支持数百万的页面浏览量。每月。 在此之前,他在Sun Microsystems工作了十多年,从事与Java有关的性能问题,并在Sun的Enterprise Java Performance团队中任职。 如果您还没有阅读过有关Java性能调优的书,并且想为解决性能问题打下良好的基础,那么这本书是您可以购买的书。 每花一分钱都是值得的。

    3. 系统性能:企业与云作者:Brendan Gregg

      系统性能企业与云 系统性能分析是所有计算机用户的一项重要技能,无论您是要了解笔记本电脑运行缓慢的原因,还是要优化大规模生产环境的性能。 它是对操作系统(内核)和应用程序性能的研究,本书将告诉您所有您需要了解的有关Linux性能监视和调整的知识。 程序员从优化算法,数据结构,JVM, 垃圾收集器开始,但是最终它们达到了系统性能发挥作用的地步。 您可能想知道为什么磁盘操作在开发设备上如此之快,但却成为生产设备上的主要问题,CPU缓存如何对您的应用程序产生如此大的影响,如何利用L1,L2和L3缓存以及物理内存在您的机器上可用。 我认为,这是每位程序员的书,不仅是Java程序员的书。 对于真正对性能调优感兴趣的任何开发人员来说,了解系统的工作方式,分页,交换和虚拟内存的工作方式,CPU如何从磁盘获取数据,不同类型的磁盘如何对受IO绑定的Java应用程序产生深远影响都是非常重要的。 我经常说, 学习JVM,但现在我可以说您必须非常了解您的系统。 知道操作系统的基本知识,系统调用,内存,CPU,网络和磁盘IO肯定会走很长一段路,并可以帮助您以任何编程语言(包括Java)编写高性能应用程序。

    4. Jack Shirazi编写的Java性能调优

      Java性能调优 这是一本有关Java性能调整和编写在Java中执行速度更快的代码的主要书籍之一。 杰克第一次写这本书时,几乎没有可用的东西。 甚至本书的第二版都已经有11年的历史了,大约在2003年发行。为什么我会推荐11年前写的东西呢? 因为它包含一些建议,实践和技术,这些建议,实践和技术即使在今天也是永恒且值得了解的。 尽管您不能按照本书的原始精神来学习本书,但应始终牢记,本书中提到的大多数内容已在后续的Java版本中得到解决。 最好的建议是在第一章中,这本书告诉我Java应用程序的性能将受到CPU,内存和IO(磁盘和网络)这三个主要因素的限制,令人惊讶的是,许多知道如何使用事件探查器的开发人员不知道这个基本事实。 我读过的经典建议“不要调整您不需要调整的内容”是最好的性能建议。 您可以看一下本书中给出的性能检查表,以了解什么是重要的,什么不是什么。 尽管这本书还介绍了许多性能分析工具,但是我建议使用诸如Scott Performances撰写的Java Performance The Definitive Guide和Binu John撰写的Java Performance这样的最新书籍,Charlie Hunt拥有更多最新列表。 您应该记住,本书不仅仅涉及JDK 1.4.0。 但是您应该查看第4至12章,其中涵盖了可应用于Java代码的各种性能提示和技术。 Jack还拥有一个站点http://www.javaperformancetuning.com/ ,该站点对于学习Java开发人员的性能调优非常有用。

    5. Java性能和可伸缩性:Henry H. Liu的定量方法

      Java性能可伸缩性定量方法 在介绍这本书之前,让我介绍作者,他是PHD,在Vmware工作,专门研究高性能和可伸缩的企业Java应用程序,但是我认为他以“软件性能和可伸缩性:定量方法”而著称。 。 您可以在本书中看到他早期畅销书的更专业版本。 顾名思义,这本书专注于Java应用程序的性能和可伸缩性。 这本书对Java开发人员,架构师甚至管理人员都有好处。 它分为两个主要部分,第一部分介绍Java性能和可伸缩性的基础知识,第二部分介绍提高性能和可伸缩性的实践。 基础部分包含四章,每章分别探讨软件程序,计算机硬件和Java虚拟机的可伸缩性。 第二部分包含各章,探讨从32位到64位如何影响 Java应用程序的性能和可伸缩性。 第6章可能是最重要的一章,它解释了如何调整Java以获得最佳的性能和可伸缩性。 它介绍了方法,实践,工具和调整Java应用程序时要牢记可伸缩性。 第7章是另一个重要的章节,它解释了设计,算法和实现如何影响任何Java应用程序的性能和可伸缩性。 它还介绍了如何执行瓶颈分析。 好在他用示例程序解释了所有这些,因此您可以在阅读时遵循准则。 总体而言,对于Java性能工程师来说,这是一本非常独特的好书,如果您喜欢阅读多本书籍以获取洞见,那么您可以将其与Java Performance The Definitive Guide and System Performance:Enterprise and Cloud一起阅读

    6. 经验丰富的Java开发人员

      扎实的Java开发人员 这是给读者的好书,我不会说这本书只关注Java性能调优,但我会说这是每个现代Java开发人员都应该拥有的书。 Ben Evans和Martjin Verburg不需要任何介绍。 他们是著名的Java专家和jClarity的创始人, jClarity有望解决云环境中的性能问题。 他们在Java方面拥有多年的经验,这在他们的《 The Well-Grounded Java Developer:Java 7的重要技术和多语言编程》中得到了体现。 我在2012年首次接触这本书,在阅读了示例章节之后,我被说服了买这本书。 这是现代Java开发人员必读的书。 它说明了Java上的新更改,包括JDK 7中的更改,例如try-with-resources,NIO2.0和并发更改。 但最重要的是,它解释了为什么向JVM添加新功能如此昂贵。 添加新的库扩展(例如fork / join或语法糖,如switch-on-string)相对容易,但添加JVM指令(如invokedynamic)则非常昂贵。 关于这本书的最好的事情可能是它不仅会停留在Java上,而且还会进一步介绍现代JVM语言,例如Scala,Clojure和Groovy。 它使用新的JVM语言和现代方法来接触函数式编程,以测试,构建和有争议的Java应用程序集成。

    这就是所有优秀的Java性能调优书籍的清单 。 我已经推荐了很多有效的Java知识,并且作为一本面向Java开发人员的书,但同时我也发现您应该有一本专门针对Java性能调优的书。 经过几年的Java工作和经验,您将不可避免地面临性能挑战,这时您应该至少了解发现瓶颈和提高Java应用程序性能的基本知识,工具和过程。 因此,如果您还没有阅读任何Java性能书籍,那么这是阅读该书的时候。

    翻译自: https://www.javacodegeeks.com/2014/07/top-5-java-performance-tuning-books-best-of-lot-must-read.html

    java必读书籍

    展开全文
  • 二 、Java 编程性能调优 03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据 04 | 慎重使用正则表达式 05 | ArrayList还是LinkedList?使用不当性能差千倍 06 | Stream如何提高遍历集合效率? 07 | 深入浅出...

    在这里插入图片描述

    目录

    前言
    怎样才能做好性能调优?
    一、概述
    01 | 如何制定性能调优标准?
    02 | 如何制定性能调优策略?
    二 、Java 编程性能调优
    03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
    04 | 慎重使用正则表达式
    05 | ArrayList还是LinkedList?使用不当性能差千倍
    06 | Stream如何提高遍历集合效率?
    07 | 深入浅出HashMap的设计与优化
    08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
    09 | 网络通信优化之序列化:避免使用Java序列化
    10 | 网络通信优化之通信协议:如何优化RPC网络通信?
    11 | 深入了解NIO的优化实现原理
    推荐几款常用的性能测试工具
    三、多线程性能调优
    12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
    13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
    14 | 多线程之锁优化(下):使用乐观锁优化并行操作
    15 | 多线程调优(上):哪些操作导致了上下文切换?
    16 | 多线程调优(下):如何优化多线程上下文切换?
    17 | 并发容器的使用:识别不同场景下最优容器
    18 | 如何设置线程池大小?
    19 | 如何用协程来优化多线程业务?
    四、JVM 性能监测及调优
    20 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
    21 | 深入JVM即时编译器JIT,优化Java编译
    22 | 如何优化垃圾回收机制?
    23 | 如何优化JVM内存分配?
    24 | 内存持续上升,我该如何排查问题?
    五、设计模式调优
    26 | 单例模式:如何创建单一对象优化系统性能?
    27 | 原型模式与享元模式:提升系统性能的利器
    28 | 如何使用设计模式优化并发编程?
    29 | 生产者消费者模式:电商库存设计优化
    30 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
    六、数据库性能调优
    32 | MySQL调优之SQL语句:如何写出高性能SQL语句?
    33 | MySQL调优之事务:高并发场景下的数据库事务调优
    34 | MySQL调优之索引:索引的失效与优化
    35 | 记一次线上SQL死锁事故:如何避免死锁?
    37 | 电商系统表设计优化案例分析
    38 | 数据库参数设置优化,失之毫厘差之千里
    39 | 答疑课堂:MySQL中InnoDB的知识点串讲
    七、实战演练场
    41 | 如何设计更优的分布式锁?
    42 | 电商系统的分布式事务调优
    43 | 如何使用缓存优化系统性能?
    44 | 记一次双十一抢购性能瓶颈调优

    后记:本着学习的态度,本篇文章案例全部手敲,在编写的同时有补充,有扩展。相信每位同学阅读后都会有很大的提升,技术共享,只要肯努力,每个人都能成为大牛!

    展开全文
  • java性能调优

    2017-02-11 22:03:00
    2. 性能调优方向: 3. 性能调优原则 (1)减小 CPU 消耗  – 线程数不易过多,过高导致线程上下文切换频繁,系统  吞吐量反而下降。 – 减少线程间的锁竞争,否则也可能切换过多 (2)CPU ...

    1. 影响性能的因素有:网路,数据库,cpu,磁盘IO,锁竞争,内存,程序本身

    2. 性能调优方向:

    3. 性能调优原则

    (1)减小 CPU 消耗 

    – 线程数不易过多,过高导致线程上下文切换频繁,系统

       吞吐量反而下降。

    – 减少线程间的锁竞争,否则也可能切换过多

    (2)CPU 没有充分利用 

    – 当线程同步文件IO,同步网络IO、锁等待、sleep时,

       线程被挂起,但资源不释放,考虑异步IO。

    (3)减小 IO 消耗 

    – 避免多个线程写同一个文件 

    • 采用缓存区方式读写(Buffered..) 

    • 异步写文件,log4j的AsyncAppender 

    • 批量读写 

    • 限流(代码中控制) 

    • 限制文件大小 

    • 网络IO 

    – 限流,根据设计限制发送次数、数据大小等  

    (4)程序调用优化

    – 串行调整为并行

    – 同步调整为异步

    – 单操作调整为批量操作

    转载于:https://my.oschina.net/feinik/blog/836092

    展开全文
  • java性能调优实战笔记

    千次阅读 2019-05-26 16:25:27
    01 | 如何制定性能调优标准? 有哪些参考因素可以体现系统的性能 CPU:有的应用长期占用CPU资源,导致其他资源无法争夺到CPU而响应缓慢。如代码递归导致的无限循环,正则表达式引起的回溯,JVM频繁的FULL GC,以及...
  • 所有的系统在开发完之后,多多少少都会有性能问题,我们首先要做的就是想办法把问题暴露出来,例如进行压力测试、模拟可能的操作场景等等,再通过性能调优去解决这些问题。好的系统性能调优不仅仅可以提高系统的性能...
  • Java应用性能调优实践

    2021-01-27 11:24:36
    应用性能的瓶颈点非常多,比如磁盘、内存、网络I/O等系统因素,Java应用代码,JVMGC,数据库,缓存等。笔者根据个人经验,将 Java性能优化分为4个层级:应用层、数据库层、框架层、JVM层,如图1所示。图
  • 【原文链接】http://coderbee.net/index.php/java/20140503/907 本文主要基于 Java performance tuning tips or everything you want to know about Java ...这篇指南主要调优 java 代码而不是 JVM 设置。
  • Java服务器调优

    2015-05-18 19:55:37
    随着成千上万的Java服务器运行在企业线上环境,Java已经成为构建线上系统的...这篇文章详细阐述了Java服务器调优的各项技术。 衡量性能  为了让我们的调优有意义,我们需要某种方法来衡量性能是否提高。让
  • Java性能调优之代码调优(一)

    千次阅读 2016-09-22 15:24:22
    下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方。原文为网络资源,但因为许多网站都认为自己为原文,无法标示原文链接。   1. 尽量在合适的场合使用单例  使用单例可以减轻加载的负担,...
  • JAVA性能调优 – 概述

    2020-12-14 10:20:29
    代码执行时间、CPU占用时间、内存分配、磁盘吞吐量、网络吞吐量、响应时间 解决性能的2个思想 木桶原理:我们首先要解决的是系统性能最差的,就比如木桶一样,最低的一块木板,才是决定木桶装多少水 Amdahl定律:...
  • 为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来。 仅当我在用Java编写的任务关键型服务器端财务应用程序中遇到严重的性能和可...
  • Java性能调优分享

    2020-09-09 20:08:30
    Java性能调优分享 这次分享还是之前在公司对项目进行性能调优时,前期的调研,以及积累的一些经验,之前公司产品面对的用户并发量较小,所以测试通过后直接上线,不需要根据其他维度来进行分析优化,后来领导对我...
  • jps用于列出Java的进程,jps还可以增加参数 -m用于输出传递给Java进程的参数 -l用于输出主函数的完整路径 -v可以用于显示传递给jvm的参数 jstat命令 jstat可以查看堆内存的使用情况以及gc情况,功能强大
  • 对于调优这个事情来说,一般就是三个过程: 性能监控:问题没有发生,你并不知道你需要调优什么?此时需要一些系统、应用的监控工具来发现问题。 性能分析:问题已经发生,但是你并...Java调优也不外乎这三步。 ...
  • Java 性能调优 (JVM CPU IO Memery)寻找性能瓶颈CPU消耗分析(以下基于linux操作系统)文件IO消耗分析(以下基于linux操作系统)网络IO消耗分析内存消耗分析程序执行慢的原因分析调优代大小调优 随着系统访问量...
  • 最近刚刚对Linux下的Java进程进行了性能调优,对用到的工具方法进行总结如下
  • 作者:张俊城, 郭理勇, 刘建 ... Java 应用性能优化是一个老生常谈的话题,典型的性能问题如页面响应慢、接口超时,服务器负载高、并发数低,数据库...Java 应用性能的瓶颈点非常多,比如磁盘、内存、网络 I/O 等系...
  • 如何制定性能调优策略 上一讲,我在介绍性能调优重要性的时候,提到了性能测试。面对日渐复杂的系统,制定合 理的性能测试,可以提前发现性能瓶颈,然后有针对性地制定调优策略。 总结一下就是“测 试 - 分析 - ...
  • 为什么要做性能调优? 一款线上产品如果没有经过性能测试,那它就好比是一颗定时炸弹,你不知道它什么时候会出现问题,你也不清楚它能承受的极限在哪儿。 所以,要不要做性能调优,这个问题其实很好回答。所有的...
  • Java性能调优

    2019-08-02 20:03:19
    网络吞吐量 响应时间 最有可能成为系统瓶颈的计算资源 磁盘IO 网络操作 CPU 异常 数据库 锁竞争 内存 加速比定义 加速比定义:加速比=优化前系统耗时/优化后系统耗时 性能调优的层次 设计调优 代码调优 JVM调优 ...
  • 测试 - 分析 - 调优 性能测试攻略 性能测试是提前能发现性能瓶颈,保障系统性能稳定的必要措施。 1.微基准性能测试 微基准性能测试可以精确定位到某个模块或者某个方法的性能问题,特别适合做一个功能模块或者一...
  • Java性能调优笔记

    2018-03-22 14:38:11
    Java性能调优读书笔记分享
  • 调优工具与操作 1.jps:jvm process status tool-java虚拟机进程状况工具 jps -l 是输出主类名 列出进程id jps -m 输出JVM启动时传递给main()的参数 jps -v 显示虚拟机参数配置 -Xms堆内存最小,-Xmx堆内存最大,-XX...
  • 如何制定性能调优标准 为什么要做性能调优? 所有系统在开发完之后,多多少少都会有性能问题,首先要做的就是想办法把问题暴露出来,再通过性能调优去解决这些问题。好的系统性能调优不仅可以提高系统的性能,还能...
  • 记一次java应用性能调优

    千次阅读 2018-05-06 22:36:02
    服务器基本配置如下 1,基本性能监控工具 top1) top 使用方式1 top 通过top命令,java应用负载极高,系统调用极高(系统调用 43% ,而用户调用只有35%),cpu的大部分资源都被系统消耗了,说明系统某部分...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,568
精华内容 22,227
关键字:

java网络调优

java 订阅