一、从Server.xml入手
Connector标签
1、protocol选择
-
org.apache.coyote.http11.Http11Protocol - blocking Java connector
-
org.apache.coyote.http11.Http11NioProtocol - non blocking Java NIO connector
-
org.apache.coyote.http11.Http11Nio2Protocol - non blocking Java NIO2 connector
-
org.apache.coyote.http11.Http11AprProtocol - the APR/native connector
并发量小的时候选择BIO,高并发的时候选择NIO,更高并发的时候选择APR
2、acceptCount
当最大请求连接maxConnections满时的最大排队大小
3、executor
指定线程池,如果不指定的话会使用默认线程池,最大线程数为200
4、keepAliveTimeout
keeAlive超时时间,该连接器在关闭连接之前将等待另一个HTTP请求的毫秒数。
默认值是使用为connectionTimeout属性设置的值。 使用值-1表示没有(即无限)超时。
5、maxConnections
最大连接数,连接满时后续连接放入最大为acceptCount的队列中.
对NIO和NIO2连接,默认值为10000;对 APR/native,默认值为8192
6、minSpareThreads
如果指定了Executor, 此属性忽略;否则为Connector创建线程池的最小活跃线程数,默认10
Executor标签
1、namePrefix
线程名称前缀
2、maxThreads
最大线程数
(int) The max number of active threads in this pool, default is 200
3、minSpareThreads
最小空闲线程
(int) The minimum number of threads (idle and active) always kept alive, default is 25
4、maxIdleTime
空闲线程关闭之前的毫秒数,除非活动线程的数目小于或等于minSpareThreads。 默认值是60000(1分钟)
5、maxQueueSize
等待队列大小,在我们拒绝执行之前可以排队等待执行的可运行任务的最大数量。
默认值为Integer.MAX_VALUE
6、prestartminSpareThreads
(布尔值)是否在启动执行程序时启动minSpareThreads,默认值为false
二、从JVM方面优化
1、内存方面
(1)程序计数器The pc Register
JVM支持多线程同时执行,每一个线程都有自己的pc register,线程正在执行的方法叫做当前方法。
如果是java代码,pcregister中存放的就是当前正在执行的指令的地址,如果是c代码,则为空。
(2)Java虚拟机栈Java Virtual Machine Stacks
Java虚拟机栈是线程私有的,它的生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型:
每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
每一个方法从调用直到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
(3)堆Heap
Java堆是Java虚拟机所管理的内存中最大的一块。是被所有线程共享的一块内存区域,在虚拟机启动时创建。
该内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。Java对象可以处于物理上
不连续的内存空间中,只要逻辑上是连续的即可。
(4)方法区Method
方法区和Java堆一样,是各个线程共享的内存区域,也是在虚拟机启动时创建。它用于存储已被虚拟机加载的类信
息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,
但是它却有一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来。
jdk1.8中就是metaspace
jdk1.6或者1.7中就是perm space
运行时常量池Runtime Constant Pool是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述
信息外,还有一项信息就是常量池,用于存放编译时期生成的各种字面量和符号引用,这部分内容将在类加载后进
入方法区的运行时常量池中存放。
(5)本地方法栈Native Method Stacks
本地方法栈和虚拟机栈锁发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈执行Java方法服务,
而本地方法栈则为虚拟机使用到的native方法服务。
2、GC算法的选择
- 串行收集器Serial:Serial、Serial Old 一个线程跑,停止,启动垃圾回收线程,回收完成,继续执行刚才暂停的线程。适用于内存比较小的嵌入式 设备中。
- 并行收集器Parallel:Parallel Scavenge、Parallel Old,吞吐量优先 多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态,适合科学计算、后台处理等弱交互场景
- 并发收集器Concurrent:CMS、G1,停顿时间优先 用户线程和垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),垃圾收集线程在执行的时候不会停 顿用户程序的运行。适合于对相应时间有要求的场景,比如Web。
- 吞吐量和停顿时间解释 吞吐量:花在垃圾收集的时间和花在应用程序时间的占比 停顿时间:垃圾收集器做垃圾回收终端应用执行的时间 小结: 评价一个垃圾回收器的好坏,其实调优的时候就是在观察者两个变量
jvm命令
1.jps 查看当前所有jvm进程
2.jinfo 查看jvm运行参数
jinfo pid
jinfo -flags
jinfo -flag UseG1GC pid
3.jstat 查看JVM统计信息
(1)类装载
jstat -class PID 1000 10
PID进程ID,1000每个一秒钟,10输出10次
(2)垃圾收集
jstat -gc PID 1000 10
3.jvm参数
X参数
非标准参数,也就是在jvm各个版本中可能会变
-Xint 解释执行
-Xcomp 第一次使用就编译成本地代码
-Xmixed 混合模式,JVM自己来决定是否编译成本地代码
XX参数
平时用的最多的参数类型
非标准化参数,相对不稳定,主要用于JVM调优和Debug
a.Boolean类型
格式:-XX:[+-]<name> 表示启用或者禁用name属性
比如:-XX:+UseConcMarkSweepGC 表示启用CMS类型的垃圾回收器
-XX:+UseG1GC 表示启用CMS类型的垃圾回收器
b.非Boolean类型
格式:-XX<name>=<value>表示name属性的值是value
比如:-XX:MaxGCPauseMillis=500
特殊参数
-Xmx -Xms 设置最大最小内存的
不是X参数,而是XX参数
-Xms等价于-XX:InitialHeapSize
-Xmx等价于-XX:MaxHeapSize
-Xss等价于-XX:ThreadStackSize
4.内存溢出和优化
内存溢出之后,怎么得到溢出信息进行分析,有两种做法
1.参数设置自动
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
2.jmap手动
查看当前进程id PID
jmap -dump:format=b,file=heap.hprof PID
jmap -heap PID 打印出堆内存相关的信息