常用命令

系统性能监控
  • 确定系统运行的整体状态,基本定位问题所在
    Java自带的工具
  • 查看Java程序运行细节,进一步定位问题

系统性能监控 linux

uptime
连接数
  • 每一个终端算一个连接
    1,5,15分钟内的系统平均负载
  • 运行队列中的平均进程数
top
vmstat
  • 可以统计系统的CPU,内存,swap,io等情况
pidstat
  • 细致观察进程
  • 需要安装( sudo apt-get install sysstat)
  • 监控CPU
  • 监控IO
  • 监控内存

-p 指定进程 –u 监控CPU 每秒采样 一共3次

Java自带的工具

jps
  • 列出java进程,类似于ps命令.
  • 参数-q可以指定jps只输出进程ID ,不输出类的短名称.
  • 参数-m可以用于输出传递给Java进程(主函数)的参数.
  • 参数-l可以用于输出主函数的完整路径.
  • 参数-v可以显示传递给JVM的参数.
jinfo
  • 可以用来查看正在运行的Java应用程序的扩展参数,甚至支持在运行时,修改部分参数
  • -flag :打印指定JVM的参数值
  • -flag [+|-]:设置指定JVM参数的布尔值
  • -flag =:设置指定JVM参数的值
jmap
  • 生成Java应用程序的堆快照和对象的统计信息
  • jmap -histo 2972 >c:\s.txt
Dump堆
  • jmap -dump:format=b,file=c:\heap.hprof 2972
jstack
  • 打印线程dump
  • -l 打印锁信息
  • -m 打印java和native的帧信息
  • -F 强制dump,当jstack没有响应时使用

内存溢出(OOM)的原因

在JVM中,有哪些内存区间?
  • 永久区
  • 线程栈
  • 直接内存
堆溢出
1
2
3
4
5
6
7
public static void main(String args[]){
ArrayList<byte[]> list=new ArrayList<byte[]>();
for(int i=0;i<1024;i++){
list.add(new byte[1024*1024]);
}
}
//占用大量的堆空间,直接溢出
1
2
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at geym.jvm.ch8.oom.SimpleHeapOOM.main(SimpleHeapOOM.java:14)

解决方法:增大堆空间,及时释放内存

永久区
1
2
3
4
5
6
//生成大量的类
public static void main(String[] args) {
for(int i=0;i<100000;i++){
CglibBean bean = new CglibBean("geym.jvm.ch3.perm.bean"+i,new HashMap());
}
}

增大Perm区、允许Class回收

Java栈溢出
  • 这里的栈溢出指,在创建线程的时候,需要为线程分配栈空间,这个栈空间是向操作系统请求的,如果操作系统无法给出足够的空间,就会抛出OOM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static class SleepThread implements Runnable{
public void run(){
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void main(String args[]){
for(int i=0;i<1000;i++){
new Thread(new SleepThread(),"Thread"+i).start();
System.out.println("Thread"+i+" created");
}
}
1
-Xmx1g -Xss1m
Exception in thread "main" java.lang.OutOfMemoryError: 
unable to create new native thread

解决方法:
减少堆内存
减少线程栈大小

直接内存溢出
  • ByteBuffer.allocateDirect()无法从操作系统获得足够的空间