日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jstat和jmap使用

發(fā)布時(shí)間:2025/6/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jstat和jmap使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

最近在做Spring Websocket后臺(tái)程序的壓力測(cè)試,但是當(dāng)并發(fā)數(shù)目在10個(gè)左右時(shí),服務(wù)器的CPU使用率一直在160%+,出現(xiàn)這個(gè)問題后,一開始很納悶,雖然服務(wù)器配置很低,但也不至于只有10個(gè)并發(fā)吧。。服務(wù)器的主要配置如下:

  • CPU:2核 Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz
  • 內(nèi)存:4GB

使用top命令查看資源占用情況,發(fā)現(xiàn)pid為9499的進(jìn)程占用了大量的CPU資源,CPU占用率高達(dá)170%,內(nèi)存占用率也達(dá)到了40%以上。?

問題排查

首先使用jstat命令來查看一下JVM的內(nèi)存情況,如下所示:

jstat -gcutil 9499 1000S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 0.00 100.00 94.92 97.44 95.30 24 0.651 8129 1147.010 1147.6610.00 0.00 100.00 94.92 97.44 95.30 24 0.651 8136 1148.118 1148.7680.00 0.00 100.00 94.92 97.44 95.30 24 0.651 8143 1149.139 1149.7890.00 0.00 100.00 94.92 97.44 95.30 24 0.651 8150 1150.148 1150.7990.00 0.00 100.00 94.92 97.44 95.30 24 0.651 8157 1151.160 1151.8110.00 0.00 100.00 94.92 97.44 95.30 24 0.651 8164 1152.180 1152.8310.00 0.00 100.00 94.92 97.44 95.30 24 0.651 8170 1153.051 1153.7010.00 0.00 100.00 94.92 97.45 95.30 24 0.651 8177 1154.061 1154.7120.00 0.00 100.00 94.93 97.45 95.30 24 0.651 8184 1155.077 1155.7280.00 0.00 100.00 94.93 97.45 95.30 24 0.651 8191 1156.089 1156.7390.00 0.00 100.00 94.93 97.45 95.30 24 0.651 8198 1157.134 1157.7850.00 0.00 100.00 94.93 97.45 95.30 24 0.651 8205 1158.149 1158.8000.00 0.00 100.00 94.93 97.45 95.30 24 0.651 8212 1159.156 1159.8070.00 0.00 100.00 94.93 97.45 95.30 24 0.651 8219 1160.179 1160.8300.00 0.00 100.00 94.93 97.45 95.30 24 0.651 8225 1161.047 1161.697
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

可以看到,Eden區(qū)域內(nèi)存占用高達(dá)100%,Old區(qū)占用高達(dá)94.9%,元數(shù)據(jù)空間區(qū)域占用高達(dá)97.4%。Young GC的次數(shù)一直是24,但是Full GC的次數(shù)卻高達(dá)幾千次,而且在程序運(yùn)行期間,頻繁發(fā)生Full GC,導(dǎo)致FGC的次數(shù)一直增加。?
雖然FGC次數(shù)一直在增加,但是卻沒有回收到任何空間,導(dǎo)致一直在運(yùn)行FGC,根據(jù)這些信息,基本可以確定是程序代碼上出現(xiàn)了問題,可能存在內(nèi)存泄漏問題,或是創(chuàng)建了不合理的大型對(duì)象。


基于上述分析,我們知道應(yīng)該是程序的問題,要定位問題,我們需要先獲取后臺(tái)程序的堆轉(zhuǎn)儲(chǔ)快照,我們使用jmap工具來生成Java堆轉(zhuǎn)儲(chǔ)快照:

jmap -dump:live,format=b,file=problem.bin 9499Dumping heap to /root/problem.bin ... Heap dump file created
  • 1
  • 2
  • 3
  • 4

下面就是對(duì)Java堆轉(zhuǎn)儲(chǔ)快照進(jìn)行分析了,我使用了Eclipse Memory Analyzer(MAT)來對(duì)快照進(jìn)行分析,在MAT打開快照文件之前,要將其后綴名修改為hprof,打開文件之后,可以發(fā)現(xiàn)如下問題:

9 instances of "org.apache.tomcat.websocket.server.WsFrameServer", loaded by "java.net.URLClassLoader @ 0xc533dc70" occupy 566,312,616 (75.57%) bytes. Biggest instances: ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xce4ef270 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xce4f1588 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xcf934b10 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xcf936e28 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xcf9620f8 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xd21c6158 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xd5dc8b30 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xd727bcf8 - 62,923,624 (8.40%) bytes. ?org.apache.tomcat.websocket.server.WsFrameServer @ 0xe768bd68 - 62,923,624 (8.40%) bytes.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

可以看到WsFrameServer的實(shí)例占用了75.57%的內(nèi)存空間,而這也就是問題所在了,那WsFrameServer為什么會(huì)占用這么高的內(nèi)存呢?我繼續(xù)用MAT來查看WsFrameServer實(shí)例的內(nèi)存分布情況:?

?
?
可以看到,WsFrameServer實(shí)例中,有兩個(gè)類型的變量占了WsFrameServer的絕大部分,它們分別是java.nio.HeapCharBuffer類的實(shí)例變量messageBufferText、java.nio.HeapByteBuffer類的實(shí)例變量messageBufferBinary。

WsFrameServer繼承自WsFrameBase ,messageBufferText和messageBufferBinary屬性就在WsFrameBase里,然后我們來debug程序,看看這兩個(gè)屬性是如何被賦值的。

public WsFrameBase(WsSession wsSession, Transformation transformation) {inputBuffer = ByteBuffer.allocate(Constants.DEFAULT_BUFFER_SIZE);inputBuffer.position(0).limit(0);messageBufferBinary = ByteBuffer.allocate(wsSession.getMaxBinaryMessageBufferSize());messageBufferText = CharBuffer.allocate(wsSession.getMaxTextMessageBufferSize());wsSession.setWsFrame(this);this.wsSession = wsSession;Transformation finalTransformation;if (isMasked()) {finalTransformation = new UnmaskTransformation();} else {finalTransformation = new NoopTransformation();}if (transformation == null) {this.transformation = finalTransformation;} else {transformation.setNext(finalTransformation);this.transformation = transformation;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

我們首先看debug結(jié)果:?


可以看到,這兩個(gè)變量的capacity都是20971520,它們是根據(jù)WsSession返回的大小來分配大小的,我們來看WsSession的方法的返回值:

private volatile int maxBinaryMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE; private volatile int maxTextMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE;static final int DEFAULT_BUFFER_SIZE = Integer.getInteger("org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE", 8 * 1024).intValue();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這兩個(gè)變量的大小默認(rèn)都是8192,那如果它們只占用8K的內(nèi)存大小,應(yīng)該也不會(huì)出現(xiàn)問題啊,那這兩個(gè)變量一定是在其他地方被修改了,我們繼續(xù)看源代碼,在WsSession的構(gòu)造方法中有如下兩行代碼:

this.maxBinaryMessageBufferSize = webSocketContainer.getDefaultMaxBinaryMessageBufferSize(); this.maxTextMessageBufferSize = webSocketContainer.getDefaultMaxTextMessageBufferSize();
  • 1
  • 2
@Override public int getDefaultMaxBinaryMessageBufferSize() {return maxBinaryMessageBufferSize; }@Override public int getDefaultMaxTextMessageBufferSize() {return maxTextMessageBufferSize; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

webSocketContainer是在WsSession的構(gòu)造方法中傳入的,webSocketContainer這兩個(gè)方法分別返回maxBinaryMessageBufferSize和maxTextMessageBufferSize的值,它們默認(rèn)為:

private int maxBinaryMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE; private int maxTextMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE;
  • 1
  • 2

即這兩個(gè)方法的默認(rèn)返回值仍然是Constants.DEFAULT_BUFFER_SIZE,即8192,那它們是在哪里改變成20971520了呢??
WsWebSocketContainer類中還有以下幾個(gè)方法:

@Override public int getDefaultMaxBinaryMessageBufferSize() {return maxBinaryMessageBufferSize; }@Override public void setDefaultMaxBinaryMessageBufferSize(int max) {maxBinaryMessageBufferSize = max; }@Override public int getDefaultMaxTextMessageBufferSize() {return maxTextMessageBufferSize; }@Override public void setDefaultMaxTextMessageBufferSize(int max) {maxTextMessageBufferSize = max; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

這幾個(gè)方法分別可以獲取和設(shè)置maxBinaryMessageBufferSize和maxTextMessageBufferSize的值,那是不是通過這幾個(gè)方法來修改的值呢??
ServletServerContainerFactoryBean類中有如下一段代碼:

public void afterPropertiesSet() {Assert.state(this.servletContext != null,"A ServletContext is required to access the javax.websocket.server.ServerContainer instance");this.serverContainer = (ServerContainer) this.servletContext.getAttribute("javax.websocket.server.ServerContainer");Assert.state(this.serverContainer != null,"Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext");if (this.asyncSendTimeout != null) {this.serverContainer.setAsyncSendTimeout(this.asyncSendTimeout);}if (this.maxSessionIdleTimeout != null) {this.serverContainer.setDefaultMaxSessionIdleTimeout(this.maxSessionIdleTimeout);}if (this.maxTextMessageBufferSize != null) {this.serverContainer.setDefaultMaxTextMessageBufferSize(this.maxTextMessageBufferSize);}if (this.maxBinaryMessageBufferSize != null) {this.serverContainer.setDefaultMaxBinaryMessageBufferSize(this.maxBinaryMessageBufferSize);} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

這個(gè)方法將在bean所有的屬性被初始化后調(diào)用,其實(shí)這兩個(gè)值就是在這修改的了。?
為什么這么說呢,我們看著兩個(gè)截圖:?

對(duì)比這兩張圖片可知,WsSession的構(gòu)造方法中傳入的wsWebSocketContainer與項(xiàng)目啟動(dòng)時(shí)的serverContainer是同一個(gè)實(shí)例。所以,在afterPropertiesSet()方法中設(shè)置的值就是在wsWebSocketContainer中設(shè)置的值。

ServletServerContainerFactoryBean類的相關(guān)屬性如下:

@Nullable private Integer maxTextMessageBufferSize;@Nullable private Integer maxBinaryMessageBufferSize;
  • 1
  • 2
  • 3
  • 4
  • 5

這兩個(gè)屬性的初始值是在servlet中設(shè)置的:

<bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean"><property name="maxTextMessageBufferSize" value="20971520"/><property name="maxBinaryMessageBufferSize" value="20971520"/> </bean>
  • 1
  • 2
  • 3
  • 4

總結(jié)

通過上述分析,也就解釋了為什么WsFrameServer占用了很大的內(nèi)存。那程序中為什么一開始將這兩個(gè)值設(shè)置這么大呢?原因是在很久以前,我們剛測(cè)試Websocket通信時(shí),發(fā)現(xiàn)只能傳輸小于8K的消息,大于8K的消息都不能進(jìn)行傳輸,所以我們干脆把它調(diào)大,也就直接設(shè)置為了20M,這也就導(dǎo)致了現(xiàn)在的這個(gè)問題。?
但是程序中發(fā)送的消息大小都是100K+的,那我也不能將他們?cè)O(shè)置太小,所以我們將其改小,設(shè)置為200K,然后重新測(cè)試,能夠達(dá)到50并發(fā)。但是,50并發(fā)感覺還是不太行,不知道能不能有其他的解決辦法~_~我再想想。

總結(jié)

以上是生活随笔為你收集整理的jstat和jmap使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 办公室大战高跟丝袜秘书经理ol | 一区二区三区伦理 | 韩日毛片| 色老头一区| 日本特黄网站 | 欧美在线一区二区视频 | 一区二区成人精品 | 免费播放毛片精品视频 | 黄色片网站免费在线观看 | 99热.com | 毛片手机在线 | 亚洲www在线 | 又色又爽又高潮免费视频国产 | 国产婷婷色一区二区三区 | 91超碰免费 | 成年人黄色片 | 在线观看成人 | 久久久久久久久99 | 国产av电影一区二区 | 国产精品视频一区在线观看 | 国产爽爽爽 | 国产精品无码久久久久久 | 久久美女精品 | 天堂网中文字幕 | 夜夜骑日日操 | 欧美三级一级片 | a毛片视频 | 色戒电影未测减除版 | 好大好爽视频 | av先锋在线| av最新网 | 欧美性猛交xxxx乱大交退制版 | jul023被夫上司连续侵犯 | 精品一二三四 | 狠狠激情 | 麻豆免费在线观看视频 | 中文字幕精品一二三四五六七八 | 国产传媒欧美日韩 | 国产综合久久久久久鬼色 | 国产网站在线免费观看 | 天天操人人爽 | 91一区 | 中文字幕2区 | 国精品人妻无码一区二区三区喝尿 | 国产1区二区 | 老牛影视av一区二区在线观看 | 国产免费又粗又猛又爽 | 免费在线视频一区 | 午夜福利电影一区 | 欧美成人三级在线视频 | 91蜜桃视频 | 精品资源在线 | 国产第2页| av中文字幕免费在线观看 | 自拍视频在线观看 | 一区高清 | 日韩欧美成人免费视频 | 麻豆免费在线播放 | 国产成人精品一区二区在线观看 | 夜夜草网 | 五月在线视频 | 自拍99页| 精品国产18久久久久久二百 | 欧美freesex黑人又粗又大 | 亚洲无码精品在线播放 | 欧美亚洲一区二区三区 | 成人在线免费视频观看 | 污污视频在线观看免费 | 黑人精品xxx一区一二区 | 婷婷五月综合缴情在线视频 | 免费看女生裸体视频 | 在线观看网页视频 | 性欧美一区二区三区 | 美女一区 | 人人爱超碰 | 欧洲国产视频 | 午夜aaa| 精品久久久久久久久久久久久久久久久 | 影音先锋伦理片 | 91九色丨porny丨国产jk | 日本黄色免费在线观看 | 国产免费看黄 | 在线免费成人网 | 欧美熟女一区二区 | 日日色av| 国产精品夜夜躁视频 | 亚洲一区二区三区综合 | av片子在线观看 | 依依av| 尤物影院在线观看 | 婷婷久久综合网 | 狠狠躁18三区二区一区视频 | 少妇4p| 欧美国产黄色 | 91精品国产日韩91久久久久久 | 日韩无码电影 | 国产麻豆精品在线 | 午夜簧片 | 免费a在线 |