JVM
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。
JVM架构图
JVM的核心是由类加载器(Class Loader)、执行引擎(Execute Engine)和Java Memory Management(JVM内存管理器)共同组成
-
JVM管理(JVM Memory Management)的内存段可分为两大类:线程共享内存和线程私有内存
-
程序计数寄存器(Program Counter Register): 每个线程有自己的计数寄存器,存储当前线程执行字节码的地址
-
jvm栈(JVM Stack): jvm会为每个运行线程分配一个栈区,线程调用方法时和方法返回时会进行入栈和出栈操作
-
本地方法栈区(Native Stack): 与jvm stack类似,只不过此区域是为调用本地方法服务(系统调用)
-
方法区(Method Area): 存储jvm加载的class、常量、静态变量、即时编译器编译后的代码等
-
java堆(Java Heap): 存储java的所有对象实例、数组等
-
线程共享内存
-
线程私有内存
-
Java Heap架构
在Java世界中使用内存不需要程序员手动申请,只需定义变量,由JVM自动为其分配相应的内存,GC负责内存垃圾回收。
-
年轻代(Young Generation): 也叫Survivor Generation
-
eden: 存放新创建的对象。
-
to|from: 存放年轻代执行minor GC后存活下来的对象
-
-
老年代(Old Generation): 存放多次年轻代执行minor GC后存活下来的对象
-
持久代(Permanent Generation): 存放java class类和meta数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 分配了一个又一个对象 放到Eden区 # 不好,Eden区满了,只能GC(新生代GC:Minor GC)了 把Eden区的存活对象copy到from区,然后清空Eden区(本来to区也需要清空的,不过本来就是空的) # 又分配了一个又一个对象 放到Eden区 # 不好,Eden区又满了,只能GC(新生代GC:Minor GC)了 把Eden区和from区的存活对象copy到to区,然后清空Eden区和from区 # 又分配了一个又一个对象 放到Eden区 # 不好,Eden区又满了,只能GC(新生代GC:Minor GC)了 把Eden区和to区的存活对象copy到from区,然后清空Eden区和to区 # ... # 有的对象来回在Survivor区呆了比如15次,就被分配到老年代Old区 # 有的对象太大,超过了Eden区,直接被分配在Old区 # 有的存活对象,放不下Survivor区,也被分配到Old区 # ... # 在某次Minor GC的过程中突然发现: # 不好,老年代Old区也满了,这是一次大GC(老年代GC:Major GC) Old区慢慢的整理一番,空间又够了 # 继续Minor GC # ...
|
tomcat常用的优化配置
-
优化tomcat进程使用的Java Heap内存空间
1 2 3 4 5 6 7 8 9 10 |
# 修改catalina.sh文件中的JAVA_OPTS JAVA_OPTS="-server -Xms512m -Xmx512m -XX:NewSize= -XX:MaxNewSize= -XX:PermSize= -XX:MaxPermSize=" -server # 服务器模型 -Xms # 堆内存初始化大小 -Xmx # 堆内存空间上限 -XX:NewSize= # 新生代空间初始化大小 -XX:MaxNewSize= # 新生代空间最大值 -XX:PermSize= # 持久代空间初始化大小 -XX:MaxPermSize= # 持久代空间最大值
|
-
线程池设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 修改server.xml文件 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" maxThreads= # 最大线程数 minSpareThreads= # 最小空闲线程数 maxSpareThreads= # 最大空闲线程数 acceptCount= # 等待队列的最大长度 URIEncoding= # URI地址编码格式,建议使用UTF-8 enableLookups= # 是否启用dns解析,建议禁用 compression= # 是否启用传输压缩机制,建议“on" compressionMinSize= # 启用压缩传输的数据流最小值,单位是字节 compressableMimeType= # 定义启用压缩功能的MIME类型。如text/html, text/xml, text/css, text/javascript Server= # 修改tomcat版本信息 />
|
-
禁用8005端口
1 2 3 |
# 修改server.xml文件 <Server port="-1" shutdown="SHUTDOWN">
|
JVM常用的分析工具
-
jps: 用来查看运行的所有jvm进程
1 2 3 4 5 6 7 8 |
jps [-q] [-mlvV] [<hostid>] -q:静默模式 -v:显示传递给jvm的命令行参数 -m:输出传入main方法的参 -l:输出main类或jar完全限定名称 -V:显示通过flag文件传递给jvm的参数 [<hostid>]:主机id,默认为localhost
|
-
jinfo: 查看进程的运行环境参数,主要是jvm命令行参数
1 2 3 4 5 |
jinfo [option] <pid> -flags:to print VM flags -sysprops:to print Java system properties -flag <name>:to print the value of the named VM flag
|
-
jstat: 对jvm应用程序的资源和性能进行实时监控
1 2 3 4 5 |
jstat -help|-options jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
常见用法 jstat -gc PID
|
-
jstack: 查看所有线程的运行状态
1 2 3 4 5 6 |
jstack [-l] <pid> jstack -F [-m] [-l] <pid> -l:long listings,会显示额外的锁信息,因此,发生死锁时常用此选项 -m:混合模式,既输出java堆栈信息,也输出C/C++堆栈信息 -F:当使用“jstack -l PID"无响应,可以使用-F强制输出信息
|
-
jmap: 查看jvm占用物理内存的状态
-
jconsole:JVM内存图形化监控工具
-
jvisualvm:JVM内存图形化监控工具