美文网首页Linux成长库
java进程工具及tomcat性能调优

java进程工具及tomcat性能调优

作者: 泡菜爱上WaSabi | 来源:发表于2018-05-30 14:59 被阅读3次
    • JVM内存管理
      首先要明白一个概念——类加载器
      class loader 类加载器,加载应用程序的类文件,及程序的类文件依赖到的其它的类文件到运行时区域中(一部分内存空间),然后交由执行引擎处理。
      Java要执行并行任务,是靠java线程来实现的
      那么线程运行在哪里呢?
      运行时区域,它就是一段内存空间,如下图,有以下几种:
      JVM内存管理.png
    • 方法区:线程共享; 用于存储被JVM加载的class信息、常量、静态变量、方法等;
    • 堆:是线程共享的,是jvm所管理的内存中占用空间最大的一部分;也是GC(Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一)管理的主要区域;主要存储对象实例、数组等;
    • Java栈:线程私有,存储线程自己的局部变量,放指令指针的,;
    • PC寄存器:程序计数寄存器,线程私有的内存空间,程序的指令指针,每一个线程都有自己的上下文,下一次该运行哪一个指令,就放到这个寄存器中;
    • 本地方法栈:线程私有
      注意
      方法区和堆内存是线程共享内存
      Java栈、pc寄存器、本地方法栈是线程自己的内存
      参考:
      Java 内存区域和GC机制:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html
      Java垃圾回收(GC)机制详解:https://www.cnblogs.com/xiaoxi/p/6486852.html

    • 堆内存区段
      Java编程语言是纯面向对象的,所以程序运行就是不断的创建对象,因为对象创建销毁不断的在发生着,对java本身来讲,堆内存成了运行时区域最大的一个内存区段,那么这个运行时区域的堆内存区段是如何划分的呢?
      我们从下图来看:

      运行在内存上的JVM进程结构.png
      主要有新生代、老年代、持久代(老版本(jdk1.6以前)有持久代,之后可能就没了)
    • 新生代:在此创建新的java对象,大多数创建完之后一次使用就结束了,活不过一次应用,每一个对象都有一个引用计数器,如果计数器为0,就表现这个对象没人用,就是该回收的垃圾,但也不一定,说不定现在没人用,一会就有人用了,所以说并不是引用计数器为0,就标识为垃圾的。而是需要等待那么一段时间,来确定是否标识为垃圾。

    • Eden区:创建新的java对象的放在此,过一会垃圾收集器来扫描,看下有没有计算器不为0的,如果有不为0的,就将这些对象挪到from区域里,但eden剩下的那些对象计数器为0的都当做垃圾回收了,空间收回来。当再次扫描时也扫描from段,如果里面还有活的,就挪
      到to区域里,接着将from和eden区域计算器为0的都清理掉,回收空间。对于to段而言,可能一会再给挪到old区段去了。

    • 存活区:分为to和from

    • 老年代:存放两朝元老对象

    • 总结:在eden区域创建对象,然后扫描,有活的就挪到from里,计算器为0的清理掉,下次再扫描时,因为from区域内已经有对象了,所以同时扫描from和eden,from里如果有活的就挪到to区域里,然后在to区域里集结的对象,一会一块挪到old区域里。这样to区域段就空了。这时再一轮扫描时,eden区域如果有活的就挪到to里,to如果有活的就挪到from里,from再集中挪到old。这样to和from的角色一直在循环转换。
      Old区域清理垃圾方法是如果计算器为0的就清理,不为0的继续在old呆着
      持久代是不会被回收的

    • 问题
      一般情况,一个java进程在运行时,它的堆内存不应该超过32G,如果超过,会产生一些垃圾收集等方面的问题,可能还会导致内存碎片,导致服务器性能下降等。假如我们给整个堆内存是20G。那么里面的新生代等区域该怎么分配呢?

    • 堆内存和里面划分的内存区段名称
      Jvm可调参数
      -Xmx:最大堆内存,它只包括新生代和老年代,因为持久代是不会变化的,而且不会回收一般在指定的配置文件定义,例如对于tomcat来讲,如果安装的是绿色包,它就会解压目录的启动脚本catalina.sh里面定义
      -Xms:初始堆内存,s表示启动时之意。也就是初始化的堆内存大小,如果不够用,就会扩展,一直扩展到最大堆内存大小定义的值。建议将初始堆内存和最大堆内存设置为一样大小,这样就省得中间去申请空间,提升了性能。
      -XX:NewSize:新生代空间初始大小,新版本可能叫-Xmn了
      -XX:MaxSize:新生代空间的最大值,MaxSize-NewSize=新生代可用的空间大小(reserved)
      -Xms -NewSize=老年代的初始空间大小
      -Xmx- MaxSize=老年代的最大空间大小
      老年代的最大值-老年代的初始值=老年代的可用空间大小(reserved)
      -XX:MaxPermSize:持久代的最大值
      -XX:PermSize:持久代的初始值
      我们不仅仅可以调整上述参数,还可以调整下述参数
      -Xss:每个线程的栈大小,也就是java栈,多数设置为1M
      -XX:NewRatio:新生代与老年代的比值,我们一般不需要特意指定新生代和老年代具体多数空间,而可以靠他们的空间比值来设置
      例:
      -XX:NewRatio=5 这个5表示1:5之意,而且都是新生代小,老年代大,所以各占六分之一和六分之五
      -XX:SurvivorRatio:Eden区与Survivor(存活区,等于from+to)的大小比值,如果设置为8,同上,就是from占十分之一,to占十分之一,eden占十分之八
      特例:
      -XX:+UseParallelGC表示使用老年代的垃圾回收算法
      -XX:+UseParNewGC表示使用并行的垃圾回收算法,例如新生代的
      -XX:+PrintGC 表示运行过程中输出GC(垃圾收集器)的信息
      -XX:+PrintGCDetail:显示GC的详细信息

    • JVM常用的分析工具:
      jps:用来查看运行的所有jvm进程,也就是java进程;
      例如:本机运行了一个tomcat进程,根据pid进程号就知道

      image.png
      jinfo:查看进程的运行环境参数,主要是jvm命令行参数;
      jstat:对jvm应用程序的资源和性能进行实时监控,类似于vmstat;
      jstack:查看所有线程栈(java栈)的运行状态;
      jmap:查看jvm占用物理内存的状态;
      jconsole:图形工具。
      jvisualvm:图形工具

    jps:Java 虚拟机进程状态管理工具

     -q:静默模式;
     -v:显示传递给jvm的命令行参数;
     -m:输出传入main方法的参数;
     -l:输出main类或jar完全限定名称;
     -V:显示通过flag文件传递给jvm的参数;
     [<hostid>]:主机id,默认为localhost;
    

    jinfo:输出给定的java进程的所有配置信息;注意查看的进程需要目前存在

    jinfo [option] <pid>
    -flags:to print VM flags
    -sysprops:to print Java system properties
    -flag <name>:to print the value of the named VM flag
    

    jstack:查看指定的java进程的线程栈的相关信息;

     jstack -F [-m] [-l] <pid>
     -l:long listings,会显示额外的锁信息,因此,发生死锁时常用此选项;
     -m:混合模式,既输出java堆栈信息,也输出C/C++堆栈信息;
     -F:当使用“jstack -l PID"无响应,可以使用-F强制输出信息;
    

    jstat:输出指定的java进程的统计信息

    jstat -help|-options
    jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
    # jstat -options
    -class:class loader
    -compiler:JIT
    -gc:gc
    -gccapacity:统计堆中各代的容量
    -gccause:
    -gcmetacapacity
    -gcnew:新生代
    -gcnewcapacity
    -gcold:老年代
    -gcoldcapacity
    -gcutil
    -printcompilation
    [<interval> [<count>]]
    interval:时间间隔,单位是毫秒;
    count:显示的次数;
    -gc:
    YGC:新生代的垃圾回收次数;
    YGCT:新生代垃圾回收消耗的时长;
    FGC:Full GC的次数;
    FGCT:Full GC消耗的时长;
    GCT:GC消耗的总时长;
    

    jmap:Memory Map, 用于查看堆内存的使用状态;

    jhat:Java Heap Analysis Tool
    jmap [option] <pid>
     查看堆空间的详细信息:
    jmap -heap <pid>
    查看堆内存中的对象的数目:
    jmap -histo[:live] <pid>
    live:只统计活动对象;
    保存堆内存数据至文件中,而后使用jvisualvm或jhat进行查看:
    jmap -dump:<dump-options> <pid>
    dump-options:
    live dump only live objects; if not specified, all objects in the heap are dumped.
    format=b binary format
    file=<file> dump heap to <file>
    

    Tomcat的常用优化配置:

    (1) 内存空间:

    /etc/sysconfig/tomcat
    JAVA_OPTS="-server -Xms -Xmx -XX:NewSize= -XX:MaxNewSize= -XX:PermSize= -XX:MaxPermSize="
    -server:服务器模型
    -Xms:堆内存初始化大小;
    -Xmx:堆内存空间上限;
    -XX:NewSize=:新生代空间初始化大小;                
    -XX:MaxNewSize=:新生代空间最大值;
    -XX:PermSize=:持久代空间初始化大小;
    -XX:MaxPermSize=:持久代空间最大值;
    

    (2) 线程池设置:

    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />```
    常用属性:
    maxThreads:最大线程数; 
    minSpareThreads:最小空闲线程数;  类似于httpd的worker模型
    maxSpareThreads:最大空闲线程数;
    acceptCount:等待队列的最大长度;
    URIEncoding:URI地址编码格式,建议使用UTF-8;
    enableLookups:是否启用dns解析,建议禁用;
    compression:是否启用传输压缩机制,建议“on";
    compressionMinSize:启用压缩传输的数据流最小值,单位是字节;至少多少才压缩
    compressableMimeType:定义启用压缩功能的MIME类型;
    text/html, text/xml, text/css, text/javascript
    

    (3) 禁用8005端口;

    <Server port="-1" shutdown="SHUTDOWN">
    

    将端口设置为“-1”即可
    示例:

    image.png

    (4) 隐藏版本信息:
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" Server="SOME STRING" />
    示例:

    image.png

    ``

    相关文章

      网友评论

        本文标题:java进程工具及tomcat性能调优

        本文链接:https://www.haomeiwen.com/subject/uodtsftx.html