日韩性视频-久久久蜜桃-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ò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩电影精品 | 国产成人精品综合在线观看 | 最新欧美日韩 | 精品午夜福利在线观看 | 国产成人啪精品 | 中文字幕久热 | 不卡福利视频 | 在线日本中文字幕 | 动漫同人高h啪啪爽文 | 久久激情网 | 爱综合网| 成人午夜在线播放 | 日日日日日日bbbbbb | 一区二区三区免费高清视频 | 岛国成人在线 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 波多野吉衣一区二区 | 用力使劲高潮了888av | 大桥未久av在线播放 | 国产视频精品免费 | 天天操夜夜操 | 天天天天天天天干 | 岛国av在线免费观看 | av手机在线播放 | 成人在线观看18 | 一级二级在线观看 | 热@国产 | 在线播放中文字幕 | 国产另类ts人妖一区二区 | 又黄又爽的网站 | 九九热在线视频免费观看 | 久久精品国产免费 | 91网页入口 | 精品少妇人妻av一区二区三区 | 呦呦av | 国产精品人妖 | 中文字幕超碰在线 | 在线一区二区三区四区五区 | 亚洲天堂欧美在线 | 亚洲成人精品一区 | 啪啪免费小视频 | 日韩簧片在线观看 | 黄色日批视频 | 欧美精品一区二区三区四区 | 大地资源二中文在线影视免费观看 | 悠悠av | 强行挺进白丝老师里呻吟 | 四虎国产 | 最新超碰| 国产黄大片 | 国产成人免费看一级大黄 | aaaa一级片| 国产成人91 | 国产精品手机在线 | 国产女人叫床高潮大片免费 | 欧美一区二区久久久 | 欧美高清久久 | 视频h在线 | 在线看成人片 | 可以免费在线观看的av | 牛牛超碰 | 日韩亚洲在线 | 91黄色国产 | 日韩国产欧美一区二区三区 | jzz在线观看| 色呦呦免费观看 | 全黄一级男人和女人 | 国产在线精品一区二区 | 久久久久无码精品国产 | 美女极度色诱图片www视频 | 在线h片| 免费观看黄色小视频 | 国产在线观看第一页 | 少妇被黑人到高潮喷出白浆 | 国产在线拍揄自揄拍无码 | 日韩成人一区二区三区 | 这里只有精品视频在线 | 最新av片| 国产毛毛片 | 床戏高潮做进去大尺度视频 | 91n在线观看 | a级片在线看 | jizz亚洲女人 | 亚洲va欧美va天堂v国产综合 | 久久永久免费 | 色大师av一区二区三区 | 免费黄色一级视频 | 亚洲精品爱爱 | 日本精品一区视频 | 96av在线视频 | 国产在线观看无码免费视频 | 日韩精品一区在线播放 | 人妻激情文学 | 精品一区二区三区人妻 | 欧美激精品 | 亚洲伊人成人网 | 免费无毒av| 黑人巨大精品欧美 | 国产在线播 |