中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

中國建設(shè)銀行網(wǎng)站會員用戶名合肥網(wǎng)站制作推廣

中國建設(shè)銀行網(wǎng)站會員用戶名,合肥網(wǎng)站制作推廣,飼料行業(yè)建設(shè)網(wǎng)站方案設(shè)計免費下載ppt,網(wǎng)絡(luò)媒體設(shè)計看此文前需已了解了運行時的數(shù)據(jù)區(qū)域和常用的垃圾回收算法,也了解了Hotspot支持的垃圾回收器。 一、cpu占用過高 cpu占用過高要分情況討論,是不是業(yè)務(wù)上在搞活動,突然有大批的流量進來,而且活動結(jié)束后cpu占用率就下降了&#xf…

看此文前需已了解了運行時的數(shù)據(jù)區(qū)域和常用的垃圾回收算法,也了解了Hotspot支持的垃圾回收器。

一、cpu占用過高

cpu占用過高要分情況討論,是不是業(yè)務(wù)上在搞活動,突然有大批的流量進來,而且活動結(jié)束后cpu占用率就下降了,如果是這種情況其實可以不用太關(guān)心,因為請求越多,需要處理的線程數(shù)越多,這是正常的現(xiàn)象。

話說回來,如果你的服務(wù)器配置本身就差,cpu也只有一個核心,這種情況,稍微多一點流量就真的能夠把你的cpu資源耗盡,這時應(yīng)該考慮先把配置提升吧。

第二種情況,cpu占用率長期過高,這種情況下可能是你的程序有那種循環(huán)次數(shù)超級多的代碼,甚至是出現(xiàn)死循環(huán)了。排查步驟如下:

(1)用top命令查看cpu占用情況

這樣就可以定位出cpu過高的進程。在linux下,top命令獲得的進程號和jps工具獲得的vmid是相同的:

?

(2)用top -Hp命令查看線程的情況

可以看到是線程id為7287這個線程一直在占用cpu

(3)把線程號轉(zhuǎn)換為16進制

[root@localhost ~]# printf "%x" 7287
1c77

記下這個16進制的數(shù)字,下面我們要用

(4)用jstack工具查看線程棧情況

[root@localhost ~]# jstack 7268 | grep 1c77 -A 10
"http-nio-8080-exec-2" #16 daemon prio=5 os_prio=0 tid=0x00007fb66ce81000 nid=0x1c77 runnable [0x00007fb639ab9000]java.lang.Thread.State: RUNNABLEat com.spareyaya.jvm.service.EndlessLoopService.service(EndlessLoopService.java:19)at com.spareyaya.jvm.controller.JVMController.endlessLoop(JVMController.java:30)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)

通過jstack工具輸出現(xiàn)在的線程棧,再通過grep命令結(jié)合上一步拿到的線程16進制的id定位到這個線程的運行情況,其中jstack后面的7268是第(1)步定位到的進程號,grep后面的是(2)、(3)步定位到的線程號。

從輸出結(jié)果可以看到這個線程處于運行狀態(tài),在執(zhí)行com.spareyaya.jvm.service.EndlessLoopService.service這個方法,代碼行號是19行,這樣就可以去到代碼的19行,找到其所在的代碼塊,看看是不是處于循環(huán)中,這樣就定位到了問題。

二、死鎖

死鎖并沒有第一種場景那么明顯,web應(yīng)用肯定是多線程的程序,它服務(wù)于多個請求,程序發(fā)生死鎖后,死鎖的線程處于等待狀態(tài)(WAITINGTIMED_WAITING),等待狀態(tài)的線程不占用cpu,消耗的內(nèi)存也很有限,而表現(xiàn)上可能是請求沒法進行,最后超時了。在死鎖情況不多的時候,這種情況不容易被發(fā)現(xiàn)。

可以使用jstack工具來查看

(1)jps查看java進程

[root@localhost ~]# jps -l
8737 sun.tools.jps.Jps
8682 jvm-0.0.1-SNAPSHOT.jar

(2)jstack查看死鎖問題

由于web應(yīng)用往往會有很多工作線程,特別是在高并發(fā)的情況下線程數(shù)更多,于是這個命令的輸出內(nèi)容會十分多。jstack最大的好處就是會把產(chǎn)生死鎖的信息(包含是什么線程產(chǎn)生的)輸出到最后,所以我們只需要看最后的內(nèi)容就行了。

Java stack information for the threads listed above:
===================================================
"Thread-4":at com.spareyaya.jvm.service.DeadLockService.service2(DeadLockService.java:35)- waiting to lock <0x00000000f5035ae0> (a java.lang.Object)- locked <0x00000000f5035af0> (a java.lang.Object)at com.spareyaya.jvm.controller.JVMController.lambda$deadLock$1(JVMController.java:41)at com.spareyaya.jvm.controller.JVMController$$Lambda$457/1776922136.run(Unknown Source)at java.lang.Thread.run(Thread.java:748)
"Thread-3":at com.spareyaya.jvm.service.DeadLockService.service1(DeadLockService.java:27)- waiting to lock <0x00000000f5035af0> (a java.lang.Object)- locked <0x00000000f5035ae0> (a java.lang.Object)at com.spareyaya.jvm.controller.JVMController.lambda$deadLock$0(JVMController.java:37)at com.spareyaya.jvm.controller.JVMController$$Lambda$456/474286897.run(Unknown Source)at java.lang.Thread.run(Thread.java:748)Found 1 deadlock.

發(fā)現(xiàn)了一個死鎖,原因也一目了然。

三、內(nèi)存泄漏

我們都知道,java和c++的最大區(qū)別是前者會自動收回不再使用的內(nèi)存,后者需要程序員手動釋放。在c++中,如果我們忘記釋放內(nèi)存就會發(fā)生內(nèi)存泄漏。但是,不要以為jvm幫我們回收了內(nèi)存就不會出現(xiàn)內(nèi)存泄漏。

程序發(fā)生內(nèi)存泄漏后,進程的可用內(nèi)存會慢慢變少,最后的結(jié)果就是拋出OOM錯誤。發(fā)生OOM錯誤后可能會想到是內(nèi)存不夠大,于是把-Xmx參數(shù)調(diào)大,然后重啟應(yīng)用。這么做的結(jié)果就是,過了一段時間后,OOM依然會出現(xiàn)。最后無法再調(diào)大最大堆內(nèi)存了,結(jié)果就是只能每隔一段時間重啟一下應(yīng)用。

內(nèi)存泄漏的另一個可能的表現(xiàn)是請求的響應(yīng)時間變長了。這是因為頻繁發(fā)生的GC會暫停其它所有線程(Stop The World)造成的。

為了模擬這個場景,使用了以下的程序

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Main {public static void main(String[] args) {Main main = new Main();while (true) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}main.run();}}private void run() {ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {executorService.execute(() -> {// do something...});}}
}

運行參數(shù)是-Xms20m -Xmx20m -XX:+PrintGC,把可用內(nèi)存調(diào)小一點,并且在發(fā)生gc時輸出信息,運行結(jié)果如下

[GC (Allocation Failure)  12776K->10840K(18432K), 0.0309510 secs]
[GC (Allocation Failure)  13400K->11520K(18432K), 0.0333385 secs]
[GC (Allocation Failure)  14080K->12168K(18432K), 0.0332409 secs]
[GC (Allocation Failure)  14728K->12832K(18432K), 0.0370435 secs]
[Full GC (Ergonomics)  12832K->12363K(18432K), 0.1942141 secs]
[Full GC (Ergonomics)  14923K->12951K(18432K), 0.1607221 secs]
[Full GC (Ergonomics)  15511K->13542K(18432K), 0.1956311 secs]
...
[Full GC (Ergonomics)  16382K->16381K(18432K), 0.1734902 secs]
[Full GC (Ergonomics)  16383K->16383K(18432K), 0.1922607 secs]
[Full GC (Ergonomics)  16383K->16383K(18432K), 0.1824278 secs]
[Full GC (Allocation Failure)  16383K->16383K(18432K), 0.1710382 secs]
[Full GC (Ergonomics)  16383K->16382K(18432K), 0.1829138 secs]
[Full GC (Ergonomics) Exception in thread "main"  16383K->16382K(18432K), 0.1406222 secs]
[Full GC (Allocation Failure)  16382K->16382K(18432K), 0.1392928 secs]
[Full GC (Ergonomics)  16383K->16382K(18432K), 0.1546243 secs]
[Full GC (Ergonomics)  16383K->16382K(18432K), 0.1755271 secs]
[Full GC (Ergonomics)  16383K->16382K(18432K), 0.1699080 secs]
[Full GC (Allocation Failure)  16382K->16382K(18432K), 0.1697982 secs]
[Full GC (Ergonomics)  16383K->16382K(18432K), 0.1851136 secs]
[Full GC (Allocation Failure)  16382K->16382K(18432K), 0.1655088 secs]
java.lang.OutOfMemoryError: Java heap space

可以看到雖然一直在gc,占用的內(nèi)存卻越來越多,說明程序有的對象無法被回收。但是上面的程序?qū)ο蠖际嵌x在方法內(nèi)的,屬于局部變量,局部變量在方法運行結(jié)果后,所引用的對象在gc時應(yīng)該被回收啊,但是這里明顯沒有。

為了找出到底是哪些對象沒能被回收,我們加上運行參數(shù)-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.bin,意思是發(fā)生OOM時把堆內(nèi)存信息dump出來。運行程序直至異常,于是得到heap.dump文件,然后我們借助eclipse的MAT插件來分析,如果沒有安裝需要先安裝。

然后File->Open Heap Dump... ,然后選擇剛才dump出來的文件,選擇Leak Suspects。

?MAT會列出所有可能發(fā)生內(nèi)存泄漏的對象

?

可以看到居然有21260個Thread對象,3386個ThreadPoolExecutor對象,如果你去看一下java.util.concurrent.ThreadPoolExecutor的源碼,可以發(fā)現(xiàn)線程池為了復(fù)用線程,會不斷地等待新的任務(wù),線程也不會回收,需要調(diào)用其shutdown方法才能讓線程池執(zhí)行完任務(wù)后停止。

其實線程池定義成局部變量,好的做法是設(shè)置成單例。

上面只是其中一種處理方法

在線上的應(yīng)用,內(nèi)存往往會設(shè)置得很大,這樣發(fā)生OOM再把內(nèi)存快照dump出來的文件就會很大,可能大到在本地的電腦中已經(jīng)無法分析了(因為內(nèi)存不足夠打開這個dump文件)。這里介紹另一種處理辦法:

(1)用jps定位到進程號

C:\Users\spareyaya\IdeaProjects\maven-project\target\classes\org\example\net>jps -l
24836 org.example.net.Main
62520 org.jetbrains.jps.cmdline.Launcher
129980 sun.tools.jps.Jps
136028 org.jetbrains.jps.cmdline.Launcher

因為已經(jīng)知道了是哪個應(yīng)用發(fā)生了OOM,這樣可以直接用jps找到進程號135988

(2)用jstat分析gc活動情況

jstat是一個統(tǒng)計java進程內(nèi)存使用情況和gc活動的工具,參數(shù)可以有很多,可以通過jstat -help查看所有參數(shù)以及含義

C:\Users\spareyaya\IdeaProjects\maven-project\target\classes\org\example\net>jstat -gcutil -t -h8 24836 1000
Timestamp         S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT29.1  32.81   0.00  23.48  85.92  92.84  84.13     14    0.339     0    0.000    0.33930.1  32.81   0.00  78.12  85.92  92.84  84.13     14    0.339     0    0.000    0.33931.1   0.00   0.00  22.70  91.74  92.72  83.71     15    0.389     1    0.233    0.622

上面是命令意思是輸出gc的情況,輸出時間,每8行輸出一個行頭信息,統(tǒng)計的進程號是24836,每1000毫秒輸出一次信息。

輸出信息是Timestamp是距離jvm啟動的時間,S0、S1、E是新生代的兩個SurvivorEden,O是老年代區(qū),M是Metaspace,CCS使用壓縮比例,YGC和YGCT分別是新生代gc的次數(shù)和時間,FGCFGCT分別是老年代gc的次數(shù)和時間,GCT是gc的總時間。雖然發(fā)生了gc,但是老年代內(nèi)存占用率根本沒下降,說明有的對象沒法被回收(當(dāng)然也不排除這些對象真的是有用)。

(3)用jmap工具dump出內(nèi)存快照

jmap可以把指定java進程的內(nèi)存快照dump出來,效果和第一種處理辦法一樣,不同的是它不用等OOM就可以做到,而且dump出來的快照也會小很多。

jmap -dump:live,format=b,file=heap.bin 24836

這時會得到heap.bin的內(nèi)存快照文件,然后就可以用eclipse來分析了。

四、總結(jié)

以上三種嚴(yán)格地說還算不上jvm的調(diào)優(yōu),只是用了jvm工具把代碼中存在的問題找了出來。我們進行jvm的主要目的是盡量減少停頓時間,提高系統(tǒng)的吞吐量。

但是如果我們沒有對系統(tǒng)進行分析就盲目去設(shè)置其中的參數(shù),可能會得到更壞的結(jié)果,jvm發(fā)展到今天,各種默認的參數(shù)可能是實驗室的人經(jīng)過多次的測試來做平衡的,適用大多數(shù)的應(yīng)用場景。

如果你認為你的jvm確實有調(diào)優(yōu)的必要,也務(wù)必要取樣分析,最后還得慢慢多次調(diào)節(jié),才有可能得到更優(yōu)的效果。

http://www.risenshineclean.com/news/22969.html

相關(guān)文章:

  • 微信群公告如何做網(wǎng)站鏈接好口碑的關(guān)鍵詞優(yōu)化
  • 成都網(wǎng)站關(guān)鍵排名2023b站免費推廣入口
  • 巢湖商城網(wǎng)站建設(shè)seo實戰(zhàn)密碼在線閱讀
  • 廣州網(wǎng)站建設(shè)外包接推廣怎么收費
  • 網(wǎng)站開發(fā)實訓(xùn)意義南寧今日頭條最新消息
  • 做黑網(wǎng)站賺錢嗎百度站長平臺
  • 網(wǎng)絡(luò)運維工程師證湖南優(yōu)化公司
  • 怎么做用戶調(diào)研網(wǎng)站重慶專業(yè)做網(wǎng)站公司
  • 商丘做網(wǎng)站漢獅網(wǎng)絡(luò)廣州百度關(guān)鍵詞推廣
  • 網(wǎng)站正在建設(shè)中的圖片素材什么是seo搜索引擎優(yōu)化
  • 鄭州市有做網(wǎng)站的嗎東莞seo廣告宣傳
  • 貴陽建設(shè)工程招投標(biāo)網(wǎng)站谷歌推廣代理商
  • 網(wǎng)站建設(shè)中圖標(biāo)網(wǎng)絡(luò)營銷方式方法
  • 西安做企業(yè)網(wǎng)站網(wǎng)站點擊軟件排名
  • 婚慶攝影企業(yè)網(wǎng)站企業(yè)seo顧問服務(wù)
  • 電腦視頻制作軟件搜索引擎優(yōu)化的定義
  • 優(yōu)惠券網(wǎng)站開發(fā)哪家好軟件推廣的渠道是哪里找的
  • 標(biāo)題設(shè)計網(wǎng)站培訓(xùn)網(wǎng)站
  • 徐州做英文網(wǎng)站的公司廣告營銷留電話網(wǎng)站
  • 網(wǎng)站開發(fā)的流程圖和原型圖百度關(guān)鍵詞優(yōu)化怎么做
  • wordpress 前端傳文件廣州seo優(yōu)化推廣
  • 網(wǎng)站優(yōu)化哪家好網(wǎng)絡(luò)營銷做的好的企業(yè)
  • 模板板網(wǎng)站關(guān)鍵詞生成器在線
  • 硬件開發(fā)工資高嗎重慶排名seo公司
  • 計算機網(wǎng)站的開發(fā)流程湖南百度推廣
  • 門戶網(wǎng)站建設(shè)美麗李守洪
  • 房屋自建設(shè)計哪個網(wǎng)站好網(wǎng)絡(luò)推廣seo教程
  • 怎么制作網(wǎng)站彈出廣告湖人最新消息
  • 營銷網(wǎng)站建設(shè)公司哪家好域名注冊商怎么查
  • 東營做網(wǎng)站m0536企業(yè)網(wǎng)站推廣注意事項