最近学Hadoop发现有必要了解一下JVM的原理及运行机制,因为Hadoop中运用的大量的JVM实例。比如NameNode、DataNode,JobTraker等。这些和守护进程在Hadoop体系中运行需要根据实际情况来自行调整相关参数。所以准备系统学习一下JVM,好了废话不多说。我们这一节讲解一下监控GC执行和JVM基本内存状态。
首先设置最简单的跟踪GC的运行参数设置如下(如何在Eclipse中设置运行参数这里不多说了,大家可以百度):
-verbose:gc在虚拟机发生内存回收时在输出设备显示信息,格式如下: [Full GC 256K->160K(124096K), 0.0042708 secs] 该参数用来监视虚拟机内存回收的情况。
然后我们新建一个类,在main方法中我们写出如下形式
运行后我们发现:
上面第一行GC也叫Minor GC,他专门负责回收年轻代区域的内存,第二行Full GC也叫Major GC他专门负责回收年老代区域的内存。1900K->536K表示年轻代GC回收了(1900-536)k大小的内存。536K->462K表示年老代GC回收了(536-462)k大小的内存.而整个年轻代和年老代区域各占有55744k的内存大小。
如果想看到更加详细的GC输出,可以将参数-XX:+PrintGC改为-XX:+PrintGCDetails继续运行之后我们发现
现在我们可以看到更加详细的GC回收,并且在程序运行完成之后,还打印了的年轻代、年老代、持久区域的内存使用情况。eden表示新生代,form和to表示两个幸存代(Survivor)区域。最下面还多出了PSPermGen表示持久代区域。
这里我解释一下[0x00000000ed160000,0x00000000ed23af50,0x00000000edfa0000)这句话的具体含义。以第一个0x00000000ed160000表示一个区域的低边界就是起始的内存地址,第二个0x00000000ed23af50表示当前边界也就是当前占用到哪个位置。第三个0x00000000edfa0000表示最高边界也就是该区域最大能申请到的位置。很显然这句话代表的这个区域并没有完全使用空闲内存区域。
其他具体含义我想不用我说了,大家都能直接看懂。
如果想每次调用GC都输出一下heap信息,则可以用这个参数-XX:+PrintGCHeapAtGC。我们执行后看到
大家可以从上面看出GC前后Heap内存形态是明显有变化的。
-XX:+TraceClassLoading监控类加载情况。配置参数后我们运行程序
我们看到了JAVA程序加载了哪些类。
另外如果想把GC输出重定向到磁盘上的一个具体的文件则可以使用-Xloggc:文件路径!