1.JVM介紹
JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫(xiě)
Java虛擬機(jī)本質(zhì)是就是一個(gè)程序,當(dāng)它在命令行上啟動(dòng)的時(shí)候,就開(kāi)始執(zhí)行保存在某字節(jié)碼文件中的指令。Java語(yǔ)言的可移植性正是建立在Java虛擬機(jī)的基礎(chǔ)上。任何平臺(tái)只要裝有針對(duì)于該平臺(tái)的Java虛擬機(jī)畅蹂,字節(jié)碼文件(.class)就可以在該平臺(tái)上運(yùn)行。這就是“一次編譯荣恐,多次運(yùn)行”液斜。
2.Tomcat介紹
a.什么是Tomcat
Tomcat和我們此前學(xué)習(xí)的 Nginx 類似,也是一個(gè)Web服務(wù)器募胃。
b.Tomcat與Nginx有什么區(qū)別旗唁?
Nginx僅支持靜態(tài)資源,而Tomcat則支持Java開(kāi)發(fā)的 jsp 動(dòng)態(tài)資源和靜態(tài)資源痹束。
Nginx適合做前端負(fù)載均衡检疫,而Tomcat適合做后端應(yīng)用服務(wù)處理。
通常情況下祷嘶,企業(yè)會(huì)使用 Nginx+tomcat 結(jié)合使用屎媳,由Nginx處理靜態(tài)資源,Tomcat處理動(dòng)態(tài)資源论巍。
3.Tomcat快速安裝
方法1:
rpm -ivh jdk-8u102-linux-x64.rpm
mkdir /app
tar xf apache-tomcat-8.0.27.tar.gz -C /app
/app/apache-tomcat-8.0.27/bin/startup.sh
方法2:
mkdir /app/
tar xf jdk-8u60-linux-x64.tar.gz -C /app/
ln -s /app/jdk1.8.0_60 /app/jdk
sed -i.ori '$a export JAVA_HOME=/app/jdk\nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH\nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
source /etc/profile
tar xf apache-tomcat-8.0.27.tar.gz -C /app
/app/apache-tomcat-8.0.27/bin/startup.sh
4.Tomcat啟動(dòng)慢解決方案
沒(méi)優(yōu)化之前啟動(dòng)時(shí)間
[root@tomcat logs]# grep 'Server startup' catalina.out
03-Aug-2019 03:15:18.225 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 591050 ms
優(yōu)化之后啟動(dòng)時(shí)間
[root@tomcat logs]# grep 'Server startup' catalina.out
03-Aug-2019 03:15:18.225 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 591050 ms
03-Aug-2019 03:22:14.112 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 1326 ms
優(yōu)化方法:
vi /usr/java/jdk1.8.0_102/jre/lib/security/java.security
securerandom.source=file:/dev/urandom
5.tomcat目錄結(jié)構(gòu)介紹
[root@tomcat apache-tomcat-8.0.27]# ll
total 92
drwxr-xr-x 2 root root 4096 Aug 3 03:05 bin #主要包含啟動(dòng)烛谊、關(guān)閉tomcat腳本和腳本依賴文件
drwxr-xr-x 3 root root 198 Aug 3 03:05 conf #tomcat配置文件目錄
drwxr-xr-x 2 root root 4096 Aug 3 03:05 lib #tomcat運(yùn)行需要加載的jar包
-rw-r--r-- 1 root root 57011 Sep 28 2015 LICENSE #license文件,不重要
drwxr-xr-x 2 root root 197 Aug 3 03:15 logs #在運(yùn)行過(guò)程中產(chǎn)生的日志文件
-rw-r--r-- 1 root root 1444 Sep 28 2015 NOTICE #不重要
-rw-r--r-- 1 root root 6741 Sep 28 2015 RELEASE-NOTES #版本特性嘉汰,不重要
-rw-r--r-- 1 root root 16204 Sep 28 2015 RUNNING.txt #幫助文件丹禀,不重要
drwxr-xr-x 2 root root 30 Aug 3 03:05 temp #存放臨時(shí)文件
drwxr-xr-x 7 root root 81 Sep 28 2015 webapps #站點(diǎn)目錄
drwxr-xr-x 3 root root 22 Aug 3 03:05 work #tomcat運(yùn)行時(shí)產(chǎn)生的緩存文件
6.tomcat配置文件
https://blog.csdn.net/yes_is_ok/article/details/82992429
#多站點(diǎn)配置文件
vim /app/apache-tomcat-8.0.27/conf/server.xml
查找host 并復(fù)制 去除注釋的字段
cp -a /app/apache-tomcat-8.0.27/webappas/* /app/apache-tomcat-8.0.27/webappas2
7.Tomcat部署zrlog
上傳代碼加啟動(dòng)
8.配置tomcat basic認(rèn)證
vim /app/apache-tomcat-8.0.27/webapps/ROOT/WEB-INF/web.xml
<web-app>
......
<security-constraint>
<web-resource-collection>
<web-resource-name>test</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>test100</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Default</realm-name>
</login-config>
</web-app>
# 添加系統(tǒng)角色
vim /app/apache-tomcat-8.0.27/conf/tomcat-users.xml
<role rolename="manager-gui"/>
<role rolename="test100"/>
<user username="tomcat" password="123456" roles="manager-gui,test100"/>
#重啟tomcat生效
9.tomcat https配置文件
vim /etc/nginx/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream tom {
server 10.0.0.7:8080;
server 10.0.0.41:8080;
}
server {
listen 443 ssl;
server_name blog.oldqiang.com;
ssl_certificate /root/ssl_key/Nginx/1_blog.oldqiang.com_bundle.crt;
ssl_certificate_key /root/ssl_key/Nginx/2_blog.oldqiang.com.key;
location / {
proxy_pass http://tom;
proxy_set_header Host $http_host;
}
}
server {
listen 80;
server_name blog.oldqiang.com;
return 302 https://$server_name$request_uri;
}
}
10.tomcat 實(shí)現(xiàn)讀寫(xiě)分離
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream tom {
server 10.0.0.7:8080;
server 10.0.0.41:8080;
}
upstream tom2{
server 10.0.0.7:8080;
}
server {
listen 443 ssl;
server_name blog.oldqiang.com;
ssl_certificate /root/ssl_key/Nginx/1_blog.oldqiang.com_bundle.crt;
ssl_certificate_key /root/ssl_key/Nginx/2_blog.oldqiang.com.key;
location / {
proxy_set_header Host $http_host;
#讀寫(xiě)分離判斷
if ( $request_method = POST ){
proxy_pass http://tom2;
}
proxy_pass http://tom;
}
#動(dòng)靜分離
location ~.*\.(png|jpg) {
root /data;
}
}
server {
listen 80;
server_name blog.oldqiang.com;
return 302 https://$server_name$request_uri;
}
}
11.使用maven編譯java項(xiàng)目
1.安裝maven,二進(jìn)制
下載maven
wget http://192.168.13.120/191118/apache-maven-3.6.1-bin.tar.gz
解壓
tar xf apache-maven-3.6.1-bin.tar.gz -C /usr/local
ln -s /usr/local/apache-maven-3.6.1/ /usr/local/maven
給maven配置環(huán)境變量
vim /etc/profile
...
export M2_HOME=/usr/local/maven
export PATH=${M2_HOME}/bin:$PATH
source /etc/profile</pre>
2: java項(xiàng)目的源碼
wget http://192.168.13.120/191118/SpringBootWeb.tar.gz
tar xf SpringBootWeb.tar.gz
SpringBoot java開(kāi)發(fā)框架
3:使用maven編譯打包
cd SpringBootWeb
?
maven源加速:
vim /usr/local/maven/conf/settings.xml
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
?
mvn clean package 先清理緩存文件,再打包
?
mvn package 打包</pre>
4:部署war包
cp target/SpringBootWeb.war /app/apache-tomcat-8.0.27/webapps2/
5: 測(cè)試訪問(wèn)
瀏覽器訪問(wèn):http://session.oldqiang.com/SpringBootWeb/
12.tomcat監(jiān)控自定義
客戶端
vim /application/apache-tomcat-8.0.27/bin/catalina.sh
CATALINA_OPTS="$CATALINA_OPTS
-Dcom.sun.management.jmxremote
-Djava.rmi.server.hostname=10.0.0.100
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false"
重啟tomcat服務(wù)
zabbix 端
#安裝zabbix-java-gateway
yum install zabbix-java-gateway.x86_64 -y
#配置zabbix-server和zabbix-java-gateway
vim /etc/zabbix/zabbix_java_gateway.conf
START_POLLERS=5
vim /etc/zabbix/zabbix_server.conf
JavaGateway=127.0.0.1
JavaGatewayPort=10052
StartJavaPollers=5
#啟動(dòng)服務(wù)
systemctl restart zabbix-java-gateway.service
systemctl restart zabbix-server.service
13.tomcat調(diào)優(yōu)化
#調(diào)優(yōu)配置解釋
[https://oldqiang.com/archives/435.html](https://oldqiang.com/archives/435.html)
請(qǐng)看一下一個(gè)時(shí)間的Java參數(shù)配置:(服務(wù)器:Linux 64Bit鞋怀,8Core×16G)
JAVA_OPTS="$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/aaa/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/aaa/dump/heap_trace.txt -XX:NewSize=1G -XX:MaxNewSize=1G"
1. ## 參數(shù)說(shuō)明
-server -Xmx3g -Xms3g -XX:MaxPermSize=128m
-XX:NewRatio=2 # eden/old 的比例
-XX:SurvivorRatio=8 # s/e的比例
-XX:+UseParallelGC
-XX:ParallelGCThreads=8
-XX:+UseParallelOldGC # 這個(gè)是JAVA 6出現(xiàn)的參數(shù)選項(xiàng)
-XX:LargePageSizeInBytes=128m # 內(nèi)存頁(yè)的大小双泪, 不可設(shè)置過(guò)大,會(huì)影響Perm的大小
-XX:+UseFastAccessorMethods # 原始類型的快速優(yōu)化
-XX:+DisableExplicitGC # 關(guān)閉System.gc()
-Xss # 是線程棧的大小
另外 -Xss 是線程棧的大小密似, 這個(gè)參數(shù)需要嚴(yán)格的測(cè)試焙矛,一般小的應(yīng)用,如果棧不是很深残腌, 應(yīng)該是128k夠用的村斟,不過(guò),我們的應(yīng)用調(diào)用深度比較大抛猫,還需要做詳細(xì)的測(cè)試蟆盹。這個(gè)選項(xiàng)對(duì)性能的影響比較大。**建議使用****256K****的大小**邑滨。
1. ## 常見(jiàn)配置匯總
1. ### 堆設(shè)置
**-Xms**:初始堆大小
**-Xmx**:最大堆大小
**-XX:NewSize=n**:設(shè)置年輕代大小
**-XX:NewRatio=n**:設(shè)置年輕代和年老代的比值日缨。如:為3,表示年輕代與年老代比值為1:3掖看,年輕代占整個(gè)年輕代年老代和的1/4
**-XX:SurvivorRatio=n**:年輕代中Eden區(qū)與兩個(gè)Survivor區(qū)的比值匣距。注意Survivor區(qū)有兩個(gè)面哥。如:3,表示Eden:Survivor=3:2毅待,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/5
**-XX:MaxPermSize=n**:設(shè)置持久代大小
1. ### 收集器設(shè)置
**-XX:+UseSerialGC**:設(shè)置串行收集器
**-XX:+UseParallelGC**:設(shè)置并行收集器
**-XX:+UseParalledlOldGC**:設(shè)置并行年老代收集器
**-XX:+UseConcMarkSweepGC**:設(shè)置并發(fā)收集器
1. ### 垃圾回收統(tǒng)計(jì)信息
**-XX:+PrintGC**
**-XX:+PrintGCDetails**
**-XX:+PrintGCTimeStamps**
**-Xloggc:filename**
1. ### 并行收集器設(shè)置
**-XX:ParallelGCThreads=n**:設(shè)置并行收集器收集時(shí)使用的CPU數(shù)尚卫。并行收集線程數(shù)。
**-XX:MaxGCPauseMillis=n**:設(shè)置并行收集最大暫停時(shí)間
**-XX:GCTimeRatio=n**:設(shè)置垃圾回收時(shí)間占程序運(yùn)行時(shí)間的百分比尸红。公式為1/(1+n)
1. ### 并發(fā)收集器設(shè)置
**-XX:+CMSIncrementalMode**:設(shè)置為增量模式吱涉。適用于單CPU情況。
**-XX:ParallelGCThreads=n**:設(shè)置并發(fā)收集器年輕代收集方式為并行收集時(shí)外里,使用的CPU數(shù)怎爵。并行收集線程數(shù)。
1. ## 調(diào)優(yōu)方法
一切都是為了這一步盅蝗,**調(diào)優(yōu)**鳖链,在調(diào)優(yōu)之前,我們需要記住下面的**原則**:
1墩莫、多數(shù)的Java應(yīng)用不需要在服務(wù)器上進(jìn)行GC優(yōu)化芙委;
2、多數(shù)導(dǎo)致GC問(wèn)題的Java應(yīng)用狂秦,都不是因?yàn)槲覀儏?shù)設(shè)置錯(cuò)誤灌侣,而是代碼問(wèn)題;
3裂问、在應(yīng)用上線之前侧啼,先考慮將機(jī)器的JVM參數(shù)設(shè)置到最優(yōu)(最適合);
4堪簿、減少創(chuàng)建對(duì)象的數(shù)量慨菱;
5、減少使用全局變量和大對(duì)象戴甩;
6、GC優(yōu)化是到最后不得已才采用的手段闪彼;
7甜孤、在實(shí)際使用中,分析GC情況優(yōu)化代碼比優(yōu)化GC參數(shù)要多得多畏腕;
GC優(yōu)化的目的有兩個(gè)([](http://www.360doc.com/content/13/0305/10/15643_269388816.shtml)[http://www.360doc.com/content/13/0305/10/15643_269388816.shtml ):](http://www.360doc.com/content/13/0305/10/15643_269388816.shtml)
[**1缴川、將轉(zhuǎn)移到老年代的對(duì)象數(shù)量降低到最小描馅;**
**2把夸、減少full GC的執(zhí)行時(shí)間;**
為了達(dá)到上面的目的铭污,一般地恋日,你需要做的事情有:
1膀篮、減少使用全局變量和大對(duì)象;
2岂膳、調(diào)整新生代的大小到最合適誓竿;
3、設(shè)置老年代的大小為最合適谈截;
4筷屡、選擇合適的GC收集器;
在上面的4條方法中簸喂,用了幾個(gè)"合適"毙死,那究竟什么才算合適,一般的喻鳄,請(qǐng)參考上面"收集器搭配"和"啟動(dòng)內(nèi)存分配"兩節(jié)中的建議扼倘。但這些建議不是萬(wàn)能的,需要根據(jù)您的機(jī)器和應(yīng)用情況進(jìn)行發(fā)展和變化诽表,實(shí)際操作中唉锌,可以將兩臺(tái)機(jī)器分別設(shè)置成不同的GC參數(shù),并且進(jìn)行對(duì)比竿奏,選用那些確實(shí)提高了性能或減少了GC時(shí)間的參數(shù)袄简。
真正熟練的使用GC調(diào)優(yōu),是建立在多次進(jìn)行GC監(jiān)控和調(diào)優(yōu)的實(shí)戰(zhàn)經(jīng)驗(yàn)上的泛啸,進(jìn)行監(jiān)控和調(diào)優(yōu)的一般步驟為:
1. **監(jiān)控GC的狀態(tài)**
使用各種JVM工具绿语,查看當(dāng)前日志,分析當(dāng)前JVM參數(shù)設(shè)置候址,并且分析當(dāng)前堆內(nèi)存快照和gc日志吕粹,根據(jù)實(shí)際的各區(qū)域內(nèi)存劃分和GC執(zhí)行時(shí)間,覺(jué)得是否進(jìn)行優(yōu)化岗仑;
1. **分析結(jié)果匹耕,判斷是否需要優(yōu)化**
如果各項(xiàng)參數(shù)設(shè)置合理,系統(tǒng)沒(méi)有超時(shí)日志出現(xiàn)荠雕,GC頻率不高稳其,GC耗時(shí)不高,那么沒(méi)有必要進(jìn)行GC優(yōu)化炸卑;如果GC時(shí)間超過(guò)1-3秒既鞠,或者頻繁GC,則必須優(yōu)化盖文;
注:**如果滿足下面的指標(biāo)嘱蛋,則一般不需要進(jìn)行****GC**:
Minor GC執(zhí)行時(shí)間不到50ms;
Minor GC執(zhí)行不頻繁,約10秒一次洒敏;
**Full GC****執(zhí)行時(shí)間不到1s龄恋;**
Full GC執(zhí)行頻率不算頻繁,不低于10分鐘1次桐玻;
1. **調(diào)整GC類型和內(nèi)存分配**
如果內(nèi)存分配過(guò)大或過(guò)小篙挽,或者采用的GC收集器比較慢,則應(yīng)該優(yōu)先調(diào)整這些參數(shù)镊靴,并且先找1臺(tái)或幾臺(tái)機(jī)器進(jìn)行beta铣卡,然后比較優(yōu)化過(guò)的機(jī)器和沒(méi)有優(yōu)化的機(jī)器的性能對(duì)比,并有針對(duì)性的做出最后選擇偏竟;
1. **不斷的分析和調(diào)整**
通過(guò)不斷的試驗(yàn)和試錯(cuò)煮落,分析并找到最合適的參數(shù)
1. **全面應(yīng)用參數(shù)**
如果找到了最合適的參數(shù),則將這些參數(shù)應(yīng)用到所有服務(wù)器踊谋,并進(jìn)行后續(xù)跟蹤蝉仇。
1. ## 調(diào)優(yōu)實(shí)例
上面的內(nèi)容都是紙上談兵,下面我們以一些真實(shí)例子來(lái)進(jìn)行說(shuō)明殖蚕。
1. ### 實(shí)例1
筆者昨日發(fā)現(xiàn)部分開(kāi)發(fā)測(cè)試機(jī)器出現(xiàn)異常:
java.lang.OutOfMemoryError: GC overhead limit exceeded
這個(gè)異常代表:GC為了釋放很小的空間卻耗費(fèi)了太多的時(shí)間轿衔,其原因一般有兩個(gè)
1. 堆太小
2. 有死循環(huán)或大對(duì)象
筆者首先排除了第2個(gè)原因,因?yàn)檫@個(gè)應(yīng)用同時(shí)是在線上運(yùn)行的睦疫,如果有問(wèn)題害驹,早就掛了。所以懷疑是這臺(tái)機(jī)器中堆設(shè)置太懈蛴宛官;
使用**ps -ef |grep "java"** 查看,發(fā)現(xiàn):
![image](https://upload-images.jianshu.io/upload_images/19559641-08743e64d64a4d25.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
該應(yīng)用的堆區(qū)設(shè)置只有768m瓦糕,而機(jī)器內(nèi)存有2g底洗,機(jī)器上只跑這一個(gè)java應(yīng)用,沒(méi)有其他需要占用內(nèi)存的地方咕娄。另外亥揖,這個(gè)應(yīng)用比較大,需要占用的內(nèi)存也比較多圣勒;
筆者通過(guò)上面的情況判斷徐块,只需要改變堆中各區(qū)域的大小設(shè)置即可,于是改成下面的情況:
![image](https://upload-images.jianshu.io/upload_images/19559641-3fdb506dee30accd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
跟蹤運(yùn)行情況發(fā)現(xiàn)灾而,相關(guān)異常沒(méi)有再出現(xiàn);
1. ### 實(shí)例2](http://www.360doc.com/content/13/0305/10/15643_269388816.shtml)
[](http://www.360doc.com/content/13/0305/10/15643_269388816.shtml)[http://www.360doc.com/content/13/0305/10/15643_269388816.shtml](http://www.360doc.com/content/13/0305/10/15643_269388816.shtml)
一個(gè)服務(wù)系統(tǒng)扳剿,**經(jīng)常出現(xiàn)卡頓旁趟,分析原因,發(fā)現(xiàn)****Full GC****時(shí)間太長(zhǎng)**:
jstat -gcutil:
S0 S1 E O P YGC YGCT FGC FGCT GCT
12.16 0.00 5.18 63.78 20.32 54 2.047 5 6.946 8.993
分析上面的數(shù)據(jù),發(fā)現(xiàn)Young GC執(zhí)行了54次锡搜,耗時(shí)2.047秒橙困,每次Young GC耗時(shí)37ms,在正常范圍耕餐,**而****Full GC執(zhí)行了5次凡傅,耗時(shí)6.946秒,每次平均1.389s肠缔,數(shù)據(jù)顯示出來(lái)的問(wèn)題是:Full GC****耗時(shí)較長(zhǎng)**夏跷,分析該系統(tǒng)的是指發(fā)現(xiàn),NewRatio=9明未,也就是說(shuō)槽华,新生代和老生代大小之比為1:9,這就是問(wèn)題的原因:
1. 新生代太小趟妥,導(dǎo)致對(duì)象提前進(jìn)入老年代猫态,觸發(fā)老年代發(fā)生Full GC;
2. 老年代較大披摄,進(jìn)行Full GC時(shí)耗時(shí)較大亲雪;
優(yōu)化的方法是調(diào)整NewRatio的值,調(diào)整到4疚膊,發(fā)現(xiàn)Full GC沒(méi)有再發(fā)生义辕,只有Young GC在執(zhí)行。這就是把對(duì)象控制在新生代就清理掉酿联,沒(méi)有進(jìn)入老年代(這種做法對(duì)一些應(yīng)用是很有用的终息,但并不是對(duì)所有應(yīng)用都要這么做)
1. ### 實(shí)例3
一應(yīng)用在性能測(cè)試過(guò)程中,發(fā)現(xiàn)內(nèi)存占用率很高贞让,F(xiàn)ull GC頻繁周崭,使用sudo -u admin -H jmap -dump:format=b,file=文件名.hprof pid 來(lái)dump內(nèi)存,生成dump文件喳张,并使用Eclipse下的mat差距進(jìn)行分析续镇,發(fā)現(xiàn):
![image](https://upload-images.jianshu.io/upload_images/19559641-36f4aa036b856b8c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
從圖中可以看出,這個(gè)線程存在問(wèn)題销部,隊(duì)列**LinkedBlockingQueue**所引用的大量對(duì)象并未釋放摸航,導(dǎo)致整個(gè)線程占用內(nèi)存高達(dá)378m,此時(shí)通知開(kāi)發(fā)人員進(jìn)行代碼優(yōu)化舅桩,將相關(guān)對(duì)象釋放掉即可酱虎。
1. ## 調(diào)優(yōu)總結(jié)
1. ### 年輕代大小選擇
* **響應(yīng)時(shí)間優(yōu)先的應(yīng)用**:**盡可能設(shè)大,直到接近系統(tǒng)的最低響應(yīng)時(shí)間限制**(根據(jù)實(shí)際情況選擇)擂涛。在此種情況下读串,年輕代收集發(fā)生的頻率也是最小的。同時(shí),減少到達(dá)年老代的對(duì)象恢暖。
* **吞吐量?jī)?yōu)先的應(yīng)用**:盡可能的設(shè)置大排监,可能到達(dá)Gbit的程度。因?yàn)閷?duì)響應(yīng)時(shí)間沒(méi)有要求杰捂,垃圾收集可以并行進(jìn)行舆床,一般適合8CPU以上的應(yīng)用。
1. ### 年老代大小選擇
* **響應(yīng)時(shí)間優(yōu)先的應(yīng)用**:年老代使用并發(fā)收集器嫁佳,所以其大小需要小心設(shè)置挨队,一般要考慮**并發(fā)會(huì)話率**和**會(huì)話持續(xù)時(shí)間**等一些參數(shù)。如果堆設(shè)置小了脱拼,可以會(huì)造成內(nèi)存碎片瞒瘸、高回收頻率以及應(yīng)用暫停而使用傳統(tǒng)的標(biāo)記清除方式;如果堆大了熄浓,則需要較長(zhǎng)的收集時(shí)間情臭。最優(yōu)化的方案,一般需要參考以下數(shù)據(jù)獲得:
* 并發(fā)垃圾收集信息
* 持久代并發(fā)收集次數(shù)
* 傳統(tǒng)GC信息
* 花在年輕代和年老代回收上的時(shí)間比例
減少年輕代和年老代花費(fèi)的時(shí)間赌蔑,一般會(huì)提高應(yīng)用的效率
* **吞吐量?jī)?yōu)先的應(yīng)用**:一般吞吐量?jī)?yōu)先的應(yīng)用都有一個(gè)很大的年輕代和一個(gè)較小的年老代俯在。原因是,這樣可以盡可能回收掉大部分短期對(duì)象娃惯,減少中期的對(duì)象跷乐,而年老代盡存放長(zhǎng)期存活對(duì)象。
1. ### 較小堆引起的碎片問(wèn)題
因?yàn)槟昀洗牟l(fā)收集器使用標(biāo)記趾浅、清除算法愕提,所以不會(huì)對(duì)堆進(jìn)行壓縮。當(dāng)收集器回收時(shí)皿哨,他會(huì)把相鄰的空間進(jìn)行合并浅侨,這樣可以分配給較大的對(duì)象。但是证膨,當(dāng)堆空間較小時(shí)如输,運(yùn)行一段時(shí)間以后,就會(huì)出現(xiàn)"碎片"央勒,如果并發(fā)收集器找不到足夠的空間不见,那么并發(fā)收集器將會(huì)停止,然后使用傳統(tǒng)的標(biāo)記崔步、清除方式進(jìn)行回收稳吮。如果出現(xiàn)"碎片",可能需要進(jìn)行如下配置:
* **-XX:+UseCMSCompactAtFullCollection**:使用并發(fā)收集器時(shí)井濒,開(kāi)啟對(duì)年老代的壓縮灶似。
* **-XX:CMSFullGCsBeforeCompaction=0**:上面配置開(kāi)啟的情況下慎陵,這里設(shè)置多少次Full GC后,對(duì)年老代進(jìn)行壓縮喻奥。
**參考資料:**
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html