三个命令
- jps 查看进程id,直接在程序运行时,直接jps
- jmap 某个时刻堆内存的情况,jdk8之前使用 jmap -heap pid,但是jdk8之后必须使用jhsdb jmap --heap --pid ***,不能使用 jmap -heap pid了,否则会报Error: -heap option used错误。
- jconsole 动态查看堆内存情况,直接jconsole ,然后弹出可视化窗口。
注意:其中1+2 要结合使用,且是静态的查看;3可以单独使用,动态查看。
jps+jmap示例
对以下代码进行查看堆的情况,先运行程序,使用jps查看pid,再在每个节点使用jhsdb jmap --heap --pid ***,查看内存情况。
package mypackage;
//测试
public class MyJava {
public static void main(String[] args) throws InterruptedException {
// 先jps命令找到进程id,然后jhsdb jmap --heap --pid ***查看堆情况
// 注意jdk8之后不能用jmap -heap ***命令查看堆情况了
System.out.println("1----");//打印1的时候看一下初始堆情况
Thread.sleep(50000);
byte[] bytes=new byte[1024*1024*10];//创建一个10兆的对象,会占用堆的内存
System.out.println("2----");//打印2的时候看一下创建了对象后堆情况
Thread.sleep(50000);
bytes=null;
System.gc();//垃圾回收
System.out.println("3----");//打印3的时候看一下垃圾回收后堆情况
Thread.sleep(50000);
}
}
初始情况下,伊甸园内存使用3兆,晋升区使用0兆,老年代0兆;
创建一个10兆的对象,直接老年代增加10兆内存;
将bytes指向null,垃圾回收后,老年代内存只剩1.5兆。
注意并不是完整的按照10兆增减,还有一些其他的不是我们手动创建的对象利用堆内存。
关于新生代,伊甸园,晋升区,老年代可自行查阅资料。
jconsole示例
上面利用jps+jmap需要手动暂停各个阶段,比较不方便,jconsole可以动态执行。