JVM基础
运行期环境代表Java平台,我们开发的程序都是.java文件,然后通过编译器编译为.class字节码文件,最后字节码被类装载器载入,进入到Java虚拟机就会被Java解释器解释执行。
JVM包括方法区,堆,Java栈,程序计数器,和本地方法栈五部分组成。
每个JVM实例都有一个方法区和一个堆,运行于JVM的所有线程都共享这些区域,当虚拟机装载类文件的时候,它解析类文件信息,并存储在方法区中,当程序运行时,生成的实例对象则存放在堆上。而每个线程都有自己的程序计数器和栈。程序计数器指向下一条即将被执行的指令,Java栈则存储条用java方法的状态,本地方法的调用状态则存储在本地方法栈。
一个JVM实例只存在一个堆内存,堆内存分为三部分,
Permanent Space 永久存储区
永久存储区是一个常驻内存区域,用于存放JDK自身携带的Class.Interface的元数据,
Young Generation Space新生区
新生区共分为三个区,伊甸区(Eden Space)、0区、1区。生成的对象实例首先存放在Eden Space,当Eden Space 满啦,则进行垃圾回收,并将剩余对象移动到0区,同理,0区满啦,则进行垃圾回收,将剩余对象移动到1区。
Tenure Generation Space 养老区垃圾回收算法
引用计数,就是一个对象拥有一个引用则累加一个计数,删除一个引用则减少一个计数,垃圾回收时,回收为0的对象。但此算法不能完成对象循环的回收。
标记清除,此算法分为两个阶段,第一个阶段标记所有被引用的对象,第二个阶段则清除没有标记的对象。缺点,会产生内存碎片。
复制,此算法就是把内存空间分为两个相同区域,每次只使用一个区域,垃圾回收时,遍历使用的区域,把正在使用的对象复制到另外一个区域,再把另外一个区域的全部清除掉,优点就是不产生碎片,但是内存空间则需要两倍内存空间。
标记整理,此算法就是先遍历一遍使用中的对象,并移动到内存区域的一端,然后清除后面的区域即可。GC分类
Scavenge GC一般情况下,当新对象生成并且在Eden Space申请空间失败就会触发Scavenge GC,然后清理遗留对象到Survivor Space,这个GC只在Eden Space发生不会影响到Old区,因为所有的新生对象都是从这里产生,所以Scanvenge GC 会频繁发生。
Full GC对整个堆进行整理,所以运行比较缓慢,应该尽量减少,导致FullGC的触发主要包括Old区被写满,持久区被写满。常用的JVM调整参数
-Xmx3550m 最大堆内存
-Xms3550m 最小堆内存(最大最小设置为一样,避免每次GC完重新内存分配)
-Xmn2g 年轻代大小,堆大小=年轻代+Old+永久区,Sun官方推荐值为整个堆的3/8
-Xss128k设置每个线程大小,根据自身应用的进行调整
-XX:MetaspaceSize=256m 设置持久代最小值(JAVA8新配置参数,之前为-XX:PermSize=)
-XX:MaxMetaspaceSize=256m 设置持久代最大值(JAVA8新配置参数,之前为-XX:MaxPermSize=)
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
具体详细的配置参数,还需要配置需要的时候查询。内存监控JVisualVM
监控调优工具有很对,比如JConsole、JProfiler,各有各的好处,下面主要讲解 JVisualVM
JVisualVM在%JAVA_HOME%/JVisualVM.exe执行。
本地监控会自动检测到,主要介绍下远程监控Tomcat,
主要分两个jstatd和jmx
jstatd配置
创建jatatd.all.policy文件
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
在远程端启动 jstatd ,需确保 hostname -i 显示的是本机IP,修改在 vi /etc/hosts
nohup jstatd -J-Djava.security.policy=jstatd.all.policy >/dev/null 2>&1 &
Jstatd配置完成。
配置Jmx
在启动参数加入一下参数
-Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
启动即可。
监控页面主要分为以下几个: