JRE、JDK和JVM简述
GC
什么是GC
GC(Garbage Collection)内存自动管理极速:内存垃圾自动回收技术[内存的分配和释放]
使用GC的好处
- 提高了软件开发的抽象度;
- 程序员可以将精力集中在实际的问题上而不用分心来管理内存的问题;
- 可以使模块的接口更加的清晰,减小模块间的偶合;
- 大减少了内存人为管理不当所带来的Bug;
使内存管理更加高效。总的说来就是GC可以使程序员可以从复杂的内存问题中摆脱出来,从而提高了软件开发的速度、质量和安全性
JVM
JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。 JVM对上层的Java源文件是不关心的,它关注的只是由源文件生成的类文件(.class文件)。
JRE
JRE是java runtime environment(java运行环境 )的缩写。光有JVM还不能让class文件执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。
在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和lib和起来就称为jre。所以,在你写完java程序编译成.class之后,你可以把这个.class文件和jre一起打包发给朋友,这样你的朋友就可以运行你写程序了(jre里有运行.class的java.exe)。
JRE是Sun公司发布的一个更大的系统,它里面就有一个JVM。JRE就与具体的CPU结构和操作系统有关,是运行Java程序必不可少的(除非用其他一些编译环境编译成.exe可执行文件......),JRE的地位就象一台PC机一样,我们写好的Win32应用程序需要操作系统帮我们运行,同样的,我们编写的Java程序也必须要JRE才能运行。
JDK
JDK是java development kit(java开发工具包 )的缩写。每个学java的人都会先在机器上装一个JDK,那 让我们看一下JDK的安装目录。在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的是以下四个文件夹:bin、include、lib、jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE包含JVM。
- bin:最主要的是编译器(javac.exe)
- include:java和JVM交互用的头文件
- lib:类库
- jre:java运行环境
(注意:这里的bin、lib文件夹和jre里的bin、lib是不同的)总的来说JDK是用于java程序的开发,而jre则是只能运行class而没有编译的功能。eclipse、idea等其他IDE有自己的编译器而不是用JDK bin目录中自带的,所以在安装时你会发现他们只要求你选jre路径就ok了。
JDK,JRE,JVM三者关系概括如下:
JDK是java程序开发时用的开发工具包,其内部也有java运行环境JRE。
JRE是java程序运行时需要的运行环境,就是说如果你光是运行java程序而不是去搞开发的话,只安装JRE就能运行已经存在的java程序了。
JDk、JRE内部都包含java虚拟机JVM,java虚拟机内部包含许多应用程序的类的解释器和类加载器等等。
java 环境管理
jdk环境变量
/etc/profile.d/java.sh
# /etc/profile.d/java.sh - set i18n stuff
export JAVA_HOME=/home/d/java/default
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$PATH
jar包管理
什么是jar包
JAR(Java Archive)是Java的归档文件,它是一种与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。
如何打/解包
使用jdk/bin/jar.exe工具,配置完环境变量后直接使得jar命令即可。
jar命令格式
jar {c t x u f }[ v m e 0 M i ][-C 目录]文件名...
{ctxu},这四个参数必须选选其一。
[v f m e 0 M i],这几个是可选参数,文件名也是必须的。
参数 说明
-c 创建一个jar包
-t 显示jar中的内容列表
-x 解压jar包
-u 添加文件到jar包中
-f 指定jar包的文件名
-v 输出详细报告
-m 指定MANIFEST.MF文件
-0 生成jar包时不压缩内容
-M 不生成清单文件MANIFEST.MF
-i 为指定的jar文件创建索引文件
-C 可在相应的目录下执行命令
关于MANIFEST.MF定义:
https://baike.baidu.com/item/MANIFEST.MF
演示
往jar包添加文件
jar uf xxx.jar BOOT-INF/classes/application.yml
解压jar包
jar -xvf xxx.jar
打jar包,不生成清单文件,不压缩
jar -cvfM0 xxx.jar BOOT-INF/ META-INF/ org/
或者
jar -cvfM0 xxx.jar *
Tomcat管理
startenv.sh
#!/bin/sh
export TOMCAT_USER="tomcat"
JAVA_OPTS="-server -Xms12G -Xmx12G"
JAVA_OPTS="$JAVA_OPTS -XX:InitialHeapSize=12G"
JAVA_OPTS="$JAVA_OPTS -XX:AutoBoxCacheMax=200000"
JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC"
JAVA_OPTS="$JAVA_OPTS -XX:+UseStringDeduplication"
JAVA_OPTS="$JAVA_OPTS -XX:+DisableExplicitGC"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDateStamps"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCTimeStamps"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintCommandLineFlags"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintTenuringDistribution"
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCApplicationStoppedTime"
JAVA_OPTS="$JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError"
JAVA_OPTS="$JAVA_OPTS -XX:HeapDumpPath=$CATALINA_BASE/logs/"
JAVA_OPTS="$JAVA_OPTS -Xloggc:$CATALINA_BASE/logs/gc.log"
JAVA_OPTS="$JAVA_OPTS -Dapp.logs=$CATALINA_BASE/logs"
JAVA_OPTS="$JAVA_OPTS -Dapp.cache=$CATALINA_BASE/cache"
JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true"
JAVA_OPTS="$JAVA_OPTS -Dvertx.cacheDirBase=/tmp"
JAVA_OPTS="$JAVA_OPTS -javaagent:/home/d/pinpoint-agent-1.8.4/pinpoint-bootstrap-1.8.4.jar -Dpinpoint.agentId=xcsale15 -Dpinpoint.applicationName=xcsale"
export JAVA_OPTS
chown -R tomcat:tomcat $CATALINA_BASE/logs
chown -R tomcat:tomcat $CATALINA_BASE/cache
chown -R tomcat:tomcat $CATALINA_BASE/conf
chown -R tomcat:tomcat $CATALINA_BASE/work
chown -R tomcat:tomcat $CATALINA_BASE/temp
chown -R tomcat:tomcat $CATALINA_BASE/webapps/xc_sale/WEB-INF/schema
Tomcat优化
更改Tomcat默认header大小
tomcat的conf/server.xml文件里,修改Connector标签,添加maxHttpHeaderSize="16384"
修改后的示例如下:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"
maxHttpHeaderSize="16384"/>
JVM排查
使用下面的命令dump出来几个文件(脚本sfa_check_v1.bat中已含有此功能)
#查看JAVA内存状态
jmap -heap 11111 > jmap_heap_11111.txt
#查看JVM堆中对象详细占用情况
jmap -histo 11111 > jmap_histo_11111.txt
#导出整个JVM中内存信息
jmap -dump:format=b,file=jmap_dump_11111.dump 11111
#查看JVM 中线程的运行状况,包括锁等待,线程是否在运行
jstack -F 11111 > jstack_F_11111.txt
#Prints additional information about locks
jstack -l 11111 > jstack_l_11111.txt
注:若导出提示存储空间不足,需要加-F......,需要切换至tomcat所在的终端进行操作。
log4j规定了默认的几个级别:ALL < trace < debug < info < warn < error < fatal < OFF
1)级别之间是包含的关系,意思是如果你设置日志级别是trace,则大于等于这个级别的日志都会输出。
2)基本上默认的级别没多大区别,就是一个默认的设定。你可以通过它的API自己定义级别。你也可以随意调用这些方法,不过你要在配置文件里面好好处理了,否则就起不到日志的作用了,而且也不易读,相当于一个规范,你要完全定义一套也可以,不用没多大必要。
3)这不同的级别的含义大家都很容易理解,这里就简单介绍一下:
trace: 是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出。
debug: 调试么,我一般就只用这个作为最低级别,trace压根不用。是在没办法就用eclipse或者idea的debug功能就好了么。
info: 输出一下你感兴趣的或者重要的信息,这个用的最多了。
warn: 有些信息不是错误信息,但是也要给程序员的一些提示,类似于eclipse中代码的验证不是有error 和warn(不算错误但是也请注意,比如以下depressed的方法)。
error: 错误信息。用的也比较多。
fatal: 级别比较高了。重大错误,这种级别你可以直接停止程序了,是不应该出现的错误么!不用那么紧张,其实就是一个程度的问题