成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

還不知道Off-Heap堆外內(nèi)存?安排!

開發(fā) 后端
今天給大家聊一個(gè)很有意思的知識(shí),就是 off-heap 堆外內(nèi)存,平時(shí)出去面試,或者研究一些技術(shù)的時(shí)候,經(jīng)常可能會(huì)遇到 off-heap 堆外內(nèi)存這個(gè)東西,但是很多人可能還不知道 off-heap 堆外內(nèi)存到底是什么,所以今天就給大家來深入的分析一下。

目錄

  • on-heap堆內(nèi)內(nèi)存是什么?
  • JVM 堆內(nèi)存是如何去劃分的?
  • JVM 堆內(nèi)存滿了后會(huì)怎么樣?
  • 基于堆外內(nèi)存解決系統(tǒng) GC 卡頓問題

今天給大家聊一個(gè)很有意思的知識(shí),就是 off-heap 堆外內(nèi)存,平時(shí)出去面試,或者研究一些技術(shù)的時(shí)候,經(jīng)常可能會(huì)遇到 off-heap 堆外內(nèi)存這個(gè)東西,但是很多人可能還不知道 off-heap 堆外內(nèi)存到底是什么,所以今天就給大家來深入的分析一下。

on-heap 堆內(nèi)內(nèi)存是什么?

要說這個(gè) off-heap 堆外內(nèi)存,就得先說 on-heap 也就是堆內(nèi)內(nèi)存,這個(gè) on-heap 堆內(nèi)內(nèi)存相信很多人應(yīng)該都是熟悉的。

那就是咱們平時(shí)寫好的 Java 系統(tǒng)其實(shí)運(yùn)行起來就是一個(gè) JVM 進(jìn)程,這個(gè) JVM 進(jìn)程是有一塊內(nèi)存空間專門給他用的,這塊內(nèi)存空間就是堆內(nèi)內(nèi)存。

大概如下圖所示:

JVM 堆內(nèi)存是如何去劃分的?

那么這里通常會(huì)產(chǎn)生什么問題呢?一般來說沒什么大問題,但是如果是遇到要把大量數(shù)據(jù)緩存在 JVM 堆內(nèi)存里的時(shí)候,就可能會(huì)有問題了。

所謂的數(shù)據(jù)緩存,意思就是說,把很多數(shù)據(jù)存放在堆內(nèi)存里,這些數(shù)據(jù)是要一直用的,所以一般來說不能把他回收掉,所以會(huì)導(dǎo)致可能很多數(shù)據(jù)一直停留在 JVM 的堆內(nèi)存里。

如下圖:

那么下一個(gè)問題來了,這個(gè) JVM 里的堆內(nèi)存是有劃分的,一塊區(qū)域是年輕代,一塊區(qū)域是老年代,像這種緩存數(shù)據(jù),因?yàn)槭情L(zhǎng)期存在堆內(nèi)存里的,所以通常會(huì)在年輕代里待一段時(shí)間,然后因?yàn)闆]法垃圾回收,給放到老年代里去。

此時(shí)如下圖:

JVM 堆內(nèi)存滿了后會(huì)怎么樣?

但是這個(gè)老年代里如果放了太多緩存數(shù)據(jù)以后,就可能會(huì)導(dǎo)致他剩余的可用空間就會(huì)比較少了,此時(shí)可能會(huì)導(dǎo)致老年代經(jīng)常會(huì)放一點(diǎn)別的數(shù)據(jù)就塞滿了,一旦塞滿了就會(huì)觸發(fā) JVM 的 Full GC,有一個(gè)垃圾回收線程會(huì)去回收老年代里的數(shù)據(jù)。

此時(shí)如下圖:

可是此時(shí)一般來說能回收的也就是除了緩存數(shù)據(jù)之外的一些空間,哪怕你回收了,但是緩存數(shù)據(jù)是要一直存在的,所以沒法回收掉。

此時(shí)會(huì)導(dǎo)致每次你回收了一部分剩余空間之后,然后還是剩余了很多緩存數(shù)據(jù),此時(shí)對(duì)于緩存數(shù)據(jù)來說會(huì)一直占據(jù)老年代的很大空間。

那么此時(shí)必然導(dǎo)致一個(gè)現(xiàn)象,那就是老年代會(huì)頻繁的寫一點(diǎn)數(shù)據(jù)就滿了,寫一點(diǎn)數(shù)據(jù)就滿了,然后一會(huì)兒就得觸發(fā)一下 Full GC。

每次 Full GC 都會(huì)導(dǎo)致 JVM 停止運(yùn)行,沒法處理外部請(qǐng)求,此時(shí)對(duì)外部來說,就會(huì)感覺你的系統(tǒng)性能經(jīng)常抖動(dòng),一會(huì)卡一下,一會(huì)兒卡一下。

所以往往來說,把很多數(shù)據(jù)緩存在 JVM 內(nèi)部,是很可能導(dǎo)致上述現(xiàn)象,就是老年代頻繁塞滿、頻繁觸發(fā) Full GC、頻繁導(dǎo)致系統(tǒng)停頓沒法處理請(qǐng)求。

如下圖:

基于堆外內(nèi)存解決系統(tǒng) GC 卡頓問題

所以針對(duì)這種情況,往往我們的優(yōu)化手段,就是會(huì)把要緩存的數(shù)據(jù),從 JVM 堆內(nèi)存里轉(zhuǎn)移到 offheap 堆外內(nèi)存里去,那所以問題來了,啥叫做堆外內(nèi)存呢?

就是顧名思義,不歸 JVM 管的內(nèi)存區(qū)域,OS 操作系統(tǒng)負(fù)責(zé)管理的一部分內(nèi)存,叫做堆外內(nèi)存。

所以我們其實(shí)可以選擇把很多數(shù)據(jù)直接寫入到堆外內(nèi)存里去,這樣的話,就不會(huì)占用 JVM 堆中的老年代空間了,也就不會(huì)導(dǎo)致老年代頻繁塞滿,頻繁觸發(fā) Full GC,導(dǎo)致系統(tǒng)性能頻繁抖動(dòng)了。

如下圖:

那既然這個(gè)堆外內(nèi)存這么好,問題來了,他有什么缺點(diǎn)呢?

當(dāng)然有了,因?yàn)槿绻阌玫氖?JVM 堆內(nèi)的內(nèi)存,你寫入了很多數(shù)據(jù)以后,如果內(nèi)存滿了,此時(shí) JVM 會(huì)自動(dòng)進(jìn)行垃圾回收,幫你釋放掉一些內(nèi)存空間,他是全自動(dòng)的。

但是如果你用的是堆外內(nèi)存,那可沒有 JVM 來幫你管理了,此時(shí)你必須自己管理那塊內(nèi)存空間。

也就是說,你寫入了數(shù)據(jù)以后,到了需要的時(shí)候,你得自己注意把部分內(nèi)存進(jìn)行釋放,所以這就導(dǎo)致了堆外內(nèi)存雖然不會(huì)導(dǎo)致你的 JVM 頻繁 GC,但是他可能會(huì)導(dǎo)致你的代碼管理難度變高。

如下圖:

那么這個(gè)堆外內(nèi)存一般來說我們用 Java 代碼是如何申請(qǐng)的呢?

看下面的代碼,一般類似 Netty、RocketMQ 等中間件因?yàn)榫褪且芾泶罅康膬?nèi)存數(shù)據(jù),所以都會(huì)選擇申請(qǐng)一塊堆外內(nèi)存,把數(shù)據(jù)放在里面,自己進(jìn)行精細(xì)化的管理。

// 定義好要申請(qǐng)的堆外內(nèi)存的大小,這里是1GB
int memorySize = 1024 * 1024 * 1024;
// 用Java里的ByteBuffer.allocateDirect方法就可以申請(qǐng)一塊堆外內(nèi)存
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(memorySize);
// 把數(shù)據(jù)寫入到堆外內(nèi)存里去
byte[] bytes = "hello world".getBytes();
byteBuffer.put(bytes);
// 從堆外內(nèi)存里讀取數(shù)據(jù)
byteBuffer.flip();
byte[] readBytes = new byte[bytes.length];
byteBuffer.get(readBytes, 0, bytes.length);

那大家通過這塊代碼看到了我們?nèi)绾紊暾?qǐng)堆外內(nèi)存,以及如何往堆外內(nèi)存里寫入數(shù)據(jù)和如何讀取數(shù)據(jù)之后,現(xiàn)在思考一下,堆外內(nèi)存我們應(yīng)該如何進(jìn)行釋放呢?

是這樣的,這個(gè)堆外內(nèi)存其實(shí)是被 JVM 堆內(nèi)的一個(gè) ByteBuffer 對(duì)象來引用的,所以如果要是 JVM 堆內(nèi)的 ByteBuffer 對(duì)象被回收了,那他關(guān)聯(lián)的堆外內(nèi)存就會(huì)被釋放了。

如下圖:

好了,今天的知識(shí)點(diǎn)就分享到這里了,相信大家看完之后應(yīng)該對(duì)堆外內(nèi)存這個(gè)概念有了一個(gè)較為清晰的認(rèn)識(shí)了。

責(zé)任編輯:姜華 來源: 石杉的架構(gòu)筆記
相關(guān)推薦

2016-07-22 17:55:07

云計(jì)算

2022-09-19 18:32:22

函數(shù)編程語言

2022-05-05 12:02:45

SCSS函數(shù)開發(fā)

2020-12-14 07:51:16

JS 技巧虛值

2018-09-02 15:43:56

Python代碼編程語言

2022-07-17 06:53:24

微服務(wù)架構(gòu)

2019-11-04 15:57:29

MySQLInnoDB內(nèi)存

2019-12-24 09:49:02

微軟英語瀏覽器

2010-03-12 09:15:28

Firefox新功能

2021-10-22 09:41:26

橋接模式設(shè)計(jì)

2023-01-02 10:08:42

StampedLocAQS框架

2018-07-10 11:33:58

計(jì)算器iPhone刪除

2021-02-03 08:24:32

JavaScript技巧經(jīng)驗(yàn)

2020-10-28 08:06:09

Vue3框架數(shù)據(jù)

2014-12-01 09:41:25

2015-07-13 08:49:54

2024-03-07 07:58:26

Web開發(fā)響應(yīng)媒體查詢工具

2021-03-18 14:02:56

iOS蘋果細(xì)節(jié)

2011-11-01 12:22:11

京東商城小i機(jī)器人

2022-06-29 10:16:25

數(shù)據(jù)庫SQL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲精品一区中文字幕乱码 | 一区二区免费在线 | 国产成人精品一区二区三区四区 | 99久久精品国产麻豆演员表 | 不卡在线视频 | 九九综合 | 国产激情三区 | 欧美中文一区 | 亚洲欧美在线观看 | 中文字幕精品视频 | 欧美久久电影 | 一二三四在线视频观看社区 | 久久精品这里 | 亚洲精品久久区二区三区蜜桃臀 | 在线观看黄色大片 | 一区二区久久 | 亚洲精品久久久一区二区三区 | 国内精品久久影院 | 日本不卡高清视频 | 99在线精品视频 | 日韩一区在线播放 | 久久乐国产精品 | 99久久久国产精品 | 黄色大片免费网站 | 精品一二三| 成人一级视频在线观看 | 国产精品美女www | 国产97碰免费视频 | 在线观看特色大片免费网站 | 亚洲高清av在线 | 一区二区视频 | 羞羞的视频网站 | 国产精品视频网 | 国产真实精品久久二三区 | 欧美美女一区二区 | 偷派自拍| 亚洲天堂影院 | 二区欧美 | 日韩在线精品视频 | 亚洲444eee在线观看 | 日韩精品一区二区在线观看 |