互联网云服务器JVM监控——JDK自带工具

背景目前,有很多公司的WEB服务器会出现CPU、内存、IO告警,运维人员往往不能及时地获取JVM等相关信息,以便分析造成告警的原因,故本文将从几个方面来阐述如何进行JVM快照,如何分析dump的快照文件,以及Tomcat调优,JVM参数调优设置和程序代码书写需要注意的问题 。
JVM学习首先,我们来看一下JAVA中的内存模型:

互联网云服务器JVM监控——JDK自带工具

文章插图
图 1
Dump JVM快照及分析Java VisualVM工具Jmap自动化获取快照性能调优Tomcat容器调优这里以Tomcat7举例说明,Tomcat7容器调优主要是在server.xml文件中对connector进行调优,添加相关属性,实现高并发 。
server.xml配置
<Connector port="8080"protocol="HTTP/1.1" maxThreads="30000"
minSpareThreads="512" maxSpareThreads="2048" enableLookups="false"
redirectPort="8443" acceptCount="35000" debug="0" connectionTimeout="40000"
disableUploadTimeout="true" URIEncoding="UTF-8" />
参数说明:
connectionTimeout
网络连接超时,单位:毫秒 。设置为0表示永不超时,这样设置有隐患的 。通常可设置为30000毫秒 。
keepAliveTimeout
长连接最大保持时间(毫秒) 。此处为15秒 。
maxKeepAliveRequests
最大长连接个数(1表示禁用,-1表示不限制个数,默认100个 。一般设置在100~200之间)
maxHttpHeaderSize
http 请求头信息的最大程度,超过此长度的部分不予处理 。一般8K 。
URIEncoding
指定Tomcat 容器的URL 编码格式 。
acceptCount
指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认为10个 。
disableUploadTimeout
上传时是否使用超时机制
enableLookups
是否反查域名,取值为:true 或false 。为了提高处理能力,应设置为false
maxSpareThreads
最大空闲连接数,一旦创建的线程超过这个值,Tomcat 就会关闭不再需要的socket线程The default value is 50.
maxThreads
最多同时处理的连接数,Tomcat 使用线程来处理接收的每个请求 。这个值表示Tomcat 可创建的最大的线程数 。
minSpareThreads
最小空闲线程数,Tomcat 初始化时创建的线程数.
minProcessors
最小空闲连接线程数,用于提高系统处理性能,默认值为10 。
maxProcessors
最大连接线程数,即:并发处理的最大请求数,默认值为75
JVM调优程序开发注意事项程序开发时,如果不理解JVM,很可能会造成内存溢出、栈溢出等问题 。
堆溢出public class HeapOOM {
 
static class OOMObject{}
/**
* @param args
*/
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<OOMObject>();
 
while(true){
list.add(new OOMObject());
}
}
}
分析:
我们上面看到堆主要是存放对象的,所以我们如果想让堆出现OOM的话,可以开一个死循环,然后产生新的对象就可以了 。然后再将堆的大小调小点 。
加上JVM参数
-verbose:gc -Xms10M -Xmx10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError,
就能很快报出OOM:
Exception in thread "main"
java.lang.OutOfMemoryError: Java heap space 。
栈溢出package com.cutesource;
 
public class StackOOM {
 
/**
* @param args
*/
 
private int stackLength = 1;
 
public void stackLeak(){
stackLength++;
stackLeak();
}
 
public static void main(String[] args) throws Throwable{
// TODO Auto-generated method stub
StackOOM oom = new StackOOM();
try{
oom.stackLeak();
}catch(Throwable err){
System.out.println("Stack length:" + oom.stackLength);
throw err;
}
}
}
分析:
我们知道栈中存放的方法执行的过程中需要的空间,所以我们可以下一个循环递归,这样方法栈就会出现OOM的异常了 。
设置JVM参数:-Xss128k,报出异常:
Exception in thread "main" java.lang.StackOverflowError
打印出Stack length:1007,这里可以看出,在我的机器上128k的栈容量能承载深度为1007的方法调用 。
方法区溢出public class MethodAreaOOM {
 
static class OOMOjbect{}
 
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub


推荐阅读