JVM内存结构:
主要分为:方法区、堆、虚拟机栈、本地方法栈、程序计数器,其中方法区和堆是线程共享的,其他的都是线程隔离的。
方法区:
主要存放类的信息、静态变量、常量、编译后的方法代码,永久代PermGen是方法区的实现,JDK1.8后永久代被移除换成了元空间Metaspace,元空间的本质和永久代类似,都是对方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。元空间大小,理论上取决于32位/64位系统可虚拟的内存大小。
堆:
唯一用途就是用来存放对象实例,根据对象的存活周期划分为新生代和老年代OldGen,两者的默认占比为1:2(即新生代:老年代),其中新生代又可以细化为Eden+From Survivor+To Survivor,默认占比为8:1:1。
虚拟机栈:
描述了Java方法执行的内存模型,每个方法执行时都会创建一个栈帧,每个方法从调用到执行完的过程就对应着一个栈帧在虚拟机中入栈到出栈的过程。栈帧存储着局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行完的过程就对应着一个栈帧在虚拟机中入栈到出栈的过程。
本地方法栈:
与虚拟机栈类似,只是虚拟机服务的对象不同而已,虚拟机栈服务的是Java方法,而本地方法栈服务的是本地方法即native方法。
程序计数器:
用于记录每条线程当前所执行到的字节码行号,以便线程切换后能恢复到正确的执行位置。因此每条线程都有独立的程序计数器,且各线程间互不影响。
tomcat调节jvm初始内存大小
windows下tomcat的运行文件为catalina.bat,打开文件,在文件中部找到“rem ----- Execute The Requested Command -----”字样 ,在它后面添加如下内容即可
set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%" rem ----- Execute The Requested Command ---------------------------------------set JAVA_OPTS=%JAVA_OPTS% -server -Xms2048m -Xmx2048m -Xmn512m -XX:PermSize=400m -XX:MaxPermSize=700mecho Using CATALINA_BASE: "%CATALINA_BASE%"echo Using CATALINA_HOME2: "%CATALINA_HOME2%"echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"if ""%1"" == ""debug"" goto use_jdkecho Using JRE_HOME: "%JRE_HOME%"goto java_dir_displayed:use_jdkecho Using JAVA_HOME: "%JAVA_HOME%":java_dir_displayedecho Using CLASSPATH: "%CLASSPATH%"
Eclipse调优:
更改eclipse.ini
做如下更改
当虚拟机进行垃圾回收时会输出GC日志到gc.log,可以将输出的gc.log上传到GC日志在线解析工具进行解析。
常见 JVM 参数说明
堆区:-Xms 初始堆大小,默认是物理内存的1/64,-Xmx 最大堆大小,物理内存的1/4,空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制因此服务器一般设置-Xms、-Xmx 相等,生产环境建议设为1024m以上-Xmn 年轻代大小-XX:NewSize 设置年轻代大小-XX:MaxNewSize 年轻代最大值非堆区:-XX:PermSize 设置持久代(perm gen)初始值(非堆内存初始值),物理内存的1/64-XX:MaxPermSize 设置持久代最大值(最大非堆内存),物理内存的1/4
与垃圾回收相关的JVM参数:
-XX:-DisableExplicitGC — 让System.gc()不产生任何作用
-XX:+PrintGCDetails — 打印GC的细节
-XX:+PrintGCDateStamps — 打印GC操作的时间戳
-XX:NewRatio — 可以设置老生代和新生代的比例
-XX:PrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布
-XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值
-XX:TargetSurvivorRatio:设置幸存区的目标使用率