java初识
java SE
java提供的标准类库
java EE
java 提供专业版类库(如JSP运行时的类库)
JDK
包含了jre 和 开发工具,包含了java SE 但没有 jave EE的类库
jre
提供了JAVA运行时的环境,可以说如果不开发java语言,只需jre,就能运行java程序。
jvm
java 程序运行时,所处的容器,可以说是web容器
tomcat
本身需要java环境才能运行。提供了使用频繁的java EE 中的类库。
tomcat 运行时组织结构(配置文件组织结构)
server{
service{
connector{}
engine{
host{}
}
}
}
# server 为顶级结构
# service 使得一个connector 对应一个 engine的,里面也可以有多个connector,但只有一个engine
# connector 连接器,用来定义客户端可以从哪连接进来,从哪个端口连接,可以定义多个connector,可以为http协议的也可以为AJP的
# engine 引擎 ,客户端连接进来,用来哪个引擎来处理一般是servelet类
# host 即虚拟主机,可以定义多个
tomcat 配置文件说明
server.xml tomcat的主配置文件
catalina.policy tomcat安全配置文件,tomcat以安全模式启动时配置
catalina.properties jvm调优参数,一般在catalina.sh 中配置或者以rpm安装时,在tomcat.conf中配置
logging.properties tomcat的日志配置文件
tomcat-users.xml tomcat的用户配置文件
----------------------------------------------------------------
以下两个是应用包的配置文件
context.xml 应用包在WEB-INF中配置的,定义的是应用包的访问路径。如果没有,就使用tomcat默认提供的context.xml
web.xml 定义应用包所需要的类,也在WEB-INF路径中配置,如果应用包没有。就使用tomcat默认提供的
注:应用包启动,就是在jvm虚拟机上跑起来。jvm虚拟机需要加载应用包启动所需的类文件(web.xml中定义的),还需要启动引擎(注意与tomcat中的引擎不是一回事)
tomcat组件
server 组件
每一个server组件就是启动一个tomcat实例
service 组件
每一个service组件定义了一个或多个connector,一个engine
connector组件
connector组件是tomcat的连接器其属性
maxThread=""
连接器的最大并发数
port=""
监听的端口号
protocol=""
连接器所用的协议
connectionTime=""
连接超时时间
address=""
监听的IP
<Connector port="18080" protocol="HTTP/1.1" connectionTimeout="20000" address="10.0.0.13" maxThreads="400" />
还有一些其他属性,具体看官方文档,或自行google
engine组件
engine是tomcat的serverlet引擎
name=""
引擎名字,使用默认
defaultHost=""
如果使用多虚拟机的话,默认的访问路径
Host组件
tomcat的虚拟主机,
name=""
虚拟主机的名字
appBase=""
虚拟主机的站点目录,如果是相对路径,相对于Catalina_BASE
而言的,一般是tomcat的解压路径。也可以是绝对路径
unpackWARS=""
war包是否自动解压
autoDeploy=""
是否自动部署
context组件
定义访问路径
<Context path="/PATH" docBase="/PATH/TO/SOMEDIR" reloadable=""/>
此处用法相当于nginx站点目录的alias
path=""
访问路径
docBase=""
为站点目录
reloadable=""
是否自动加载
tomcat jvm 内存组成

- 方法区: 存放java类的方法,也可称为对象的方法
- 堆内存: 存放java对象,也可以理解为存放数据的
- java栈: 存放java局部变量的
- PC计数器: 存放java进程指令集的
-
本地方法栈: 调用本地的函数库,一般不用。不利于代码移植
注:方法区和堆内存是面对整个java进程的
注:java栈和PC计数器只面对单个java线程的
GC(垃圾回收)
由于堆内存是存放数据的,因此堆内存也最消耗内存空间,需要进行垃圾回收(即内存回收机制)
内存回收算法
复制

- 先标记FROM中存活的对象
- 将FROM中的存活对象,复制到TO中
- 第二次GC时,TO变成了FROM,FROM变成了TO
- 把FROM中的存活对象复制到TO中
- 依次循环
复制算法中,FROM和TO是相互转换的
效率高,不会有碎片产生,但会占用双倍的内存
标记-清除

- 先找到存活的对象,对其进行标记
- 对其不存活对象在进行清除
不会占用双倍内存,但有碎片产生
标记-压缩

- 先找到存活对象进行标记
- 把存活的对象与不存活对象进行交换
- 清除不存活对象
会有移动计算代价,因为不确定,存活对象与不存活对象交换时,两者所占用的内存空间是否一致
标记-清除-压缩
- 先找到存活对象进行标记
- 把不存活对象进行清除
- 进行移动存活对象,使之合并在一起
无需移动计算代价,但需要三次遍历,时间长
JVM GC 机制
GC 机制在哪出现

- 新生代: Minjor GC 小GC
- 老年代: Manjor GC 大GC
- 永久代: per GC
新生代,是新建的java对象存放位置,大部分都会释放,因此新生代,发生GC的频率最高。
老年代,是新生代存活下来的对象。转到老年代,GC频率较少
永久代,当内存不够用时,才会触发GC
当老年代和永久代同时触发GC时,会出现full GC,此时tomcat会停下所有的线程,专门进行垃圾回收线程,tomcat就会出现假死状态
新生代 GC 机制
新生代采用复制算法,因为其GC频率较高,且需要快速响应
- 串行 GC
适用于JDK运行为client端,和单核CPU上,只有一个垃圾回收线程 - 并行 GC
server 端的默认选项,适用于多核cpu - parnew
并行的执行串行GC,于CMS(老年代GC 机制),一起适用减少STW(stop-the-world停止所有应用的时间)
老年代GC
老年代由于GC频率较少,执行标记-清除-压缩算法
- 串行GC
适用于client 端,有 STW -
并行 GC
适用于server端和多核cpu
image.png
1 .先标记出找出存活对象
2 .在找出碎片比较多的region
3 .把region进行压缩 - CMS
并发线程,标记清除,无STW(或者停机时间最短)
1 .先初始化标记存活对象 (STW短)
2 .在第一步基础上,在标记一下 ,存活对象
3 .在第二步基础上,在进行标记存活对象 (STW 短)
4 .将不存活对象进行清除
并发线程,在执行tomcat应用进程的时候,同时进行GC进程。因为是标记-清除,所以有碎片产生,可以手动指定参数,清除完之后,进行压缩。因为是并发,消耗内存和cpu。所以应指定老年代内存到了多少进行CMS,默认68%,如果预留的内存不够进行CMS,则CMS降级到串行GC
新生代和老年代的GC机制搭配

- 单机或client端
串行====》 串行 - 关注吞吐量
并行 ====》 并行 - 关注访问时间(web服务,互联网应用)
parnew===》CMS
tomcat 调优
堆内存调优
一般来说堆越大越好,可以减少GC频率。但堆过大,会增加GC时间。要把握一个平衡,但总体保持一个原则尽可能减少GC频率。
一般情况下,-Xms 和 -Xmn 设置成一样,因为每次堆内存调整,都会触发fullGC。但并不是都这样,当内存足够大时,-Xmn 应比 -Xms 大,因为fullGC 总比 OOM 或者 宕机好
-Xms
堆内存的初始大小
-Xmn
堆内存的最大大小
新生代调优-增大Eden 空间
增大Eden大小
- 可以降低GC 频率
- 不会增加 Minjor GC 时间,因为新生代采用复制算法。Minjor GC 的耗时,和要拷贝的对象数量及存活对象成正比。
-XX:NewSize
新生代初始大小
-XX:MaxNewSize
新生代的最大值
-XX:NewRation=n
新生代和老年代的比值
-Xmn
新生代的大小
处于性能考虑,一般使用-Xmn 固定新生代的大小
新生代调优-晋升
尽可能让对象呆在survivor中,使之在新生代中回收,减少晋升到旧生代得对象,降低旧生代的GC频率,可以加大survivor空间
-XX:survivorRatio=m
Eden和survivor的比值
注:旧生代和老年代是一样的,只是叫法不同
旧生代调优
尽可能让GC发生在新生代
输出GC日志
-XX:+PrintGC 输出GC简要信息
-XX:+PrintGCDetails 输出GC详细信息
-XX:+PrintGCTimeStamps 输出GC的时间戳
-XX:+PrintGCApplicationStoppedTime 输出GC暂停时间
-Xlog /opt/gc.log 输出GC日志
jdk 自带工具说明
jps
[root@db03 bin]# ./jps -help
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
用法 | 描述 |
---|---|
jps -q | 输出VM标识符 |
jps -m | 输出main methond参数 |
jps -l | 输出完全包名,应用主类名,jar 完全路径名 |
jps -v | 输出 JVM参数 |
jps -V | 输出通过flag 文件传递到JVM的参数 |
jstat
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
interval 间隔时间,单位为妙或者毫秒
count打印次数,如果是缺省打印则无数次
[root@db03 bin]# ./jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation
用法 | 描述 |
---|---|
jstat -gc pid | 显示gc信息,查看gc的次数及时间 |
jstat -gccappacity pid | 内存GC分区中各对象的使用和占用大小 |
jstat -gcutil pid | 统计gc信息汇总 |
jstat -gcnew pid | 新生代 对象的信息 |
jstat -gcnewcapacity pid | 新生代对象的信息及其占用量 |
jstat -gcold pid | 老年代对象的信息 |
jstat -gcoldcapactiy pid | 老年代对象及其信息占用量 |
jsstat -gcpermcapactiy pid | perm 对象的信息及其占用量,永久代的 |
jstat -class pid | 显示加载class的数量及其占用空间 |
jstat -compiler pid | 显示JVm实时变异的数量等信息 |
jstat -printcompilation pid | 打印当前JVM执行的信息 |
jstat -gc 详解
S0: heap上的 Survivor space 0区使用空间占用百分比
S1: heap 上 Survivor space 1 区使用空间的百分比
E: heap上的Eden space是所占百分比
O: heap上的old space区已使用空间的百分比
P: Perm space 已使用空间的百分比
YGC: 从应用程序启动到采样发生young GC的次数
YGCT:从应用程序启动到采样时,Young GC所用的时间(单位秒)
FGC: 从应用程序启动到采样时,发生full GC的次数
FGCT: 从应用程序启动到采样Full GC 所用的时间(单位秒)
GCT: 从应用程序启动到采样时,用于垃圾回收的总时间(单位秒)
GC比例不同应该调整的区域
-
YGC 频繁
eden区太小 -
FGC频繁
旧生代太小 -
YGC不频繁,FGC频繁
新生代和老年代比例分配不均导致 -
YGC 和 FGC都频繁
增大堆内存
jinfo
jinfo 可以查看运行中JVM的全部参数,还可以设置部分参数
[root@db03 bin]# ./jinfo
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message
参数/option | 描述 |
---|---|
pid | 对应JVM 的pid |
-flag name | 输出对应名称的参数 |
-flag [+/-]name | 开启/关闭对应名称的参数 |
-flag name=value | 设定对应名称的参数 |
-flags | 输出全部的参数 |
-sysprops | 输出系统属性 |
tomcat调优总结
堆内存调优
- 新生代调优
eden
对象晋升条件 - 指定垃圾回收器
-XX:
UseSerialGC: 运行与client模式下,老年代使用Serialold
UseParNewGC:新生代Parnew,老年代Serialold
UseParalellGC: 运行与server模式下,新生代使用 Servial Scavenge 老年代使用paraellold
UseParalellOldGC:新生代使用Paraell scavenge,老年代使用Parell Old
UseConMarkSeepGC:新生代使用ParNew,老年代优先使用CMS,备选方式 servial old
-XX:
UseCMSCompactFullCollection: CMS完成内存回收后是否进行内存整理
CMSInitiatingOccupancyFraction: 设定老年代空间占用比例达到多少是触发回收操作,默认68%
CMSFullGGsBeforeCompaction:在多少次回收后执行一次内存碎片整理
线程池设置
`maxThread=""` 连接器的最大并发数
`port=""` 监听的端口号
`protocol=""` 连接器所用的协议
`connectionTime=""` 连接超时时间
`address=""` 监听的IP
网友评论