JVM菜鳥進階高手之路十一(eden survivor分配問題)

来源:http://www.cnblogs.com/lirenzuo/archive/2017/09/16/7531919.html
-Advertisement-
Play Games

轉載請註明原創出處,謝謝! 問題 這個Xmn設置為1G,,我用jmap heap 看,這個Eden From To怎麼不是一個整8:1:1的關係呢? 我看記憶體分配還是沒變,我Xmn1g,感覺From、To應該都是102.4M才對,現在是102.375M。 執行命令 結果: 發現很奇怪,的確和我們相信 ...


轉載請註明原創出處,謝謝!

問題

這個Xmn設置為1G,,我用jmap -heap 看,這個Eden From To怎麼不是一個整8:1:1的關係呢?
我看記憶體分配還是沒變,我Xmn1g,感覺From、To應該都是102.4M才對,現在是102.375M。

執行命令

jstat -gc pid 1s 1

結果:


發現很奇怪,的確和我們相信的不一樣,我覺得只有源碼可以告訴我們他做了啥。查看源碼:

執行上面的例子代碼

    public static void main(String[] args) {
        System.out.println(107374183&~((1<<16)-1));
    }

輸出結果為:
107347968

104832K * 1024剛剛好等於107347968B


R大以前的回覆:

從該信息中可以得到:Oracle/Sun JDK及OpenJDK里的HotSpot VM的話預設GC堆里的對象用8位元組對齊。

java記憶體參數對齊問題

上面問題其實就是java記憶體參數對齊問題。那麼為什麼需要java記憶體參數對齊問題?

記憶體對齊(Data Structure Alignment)是什麼?

記憶體對齊,或者說位元組對齊,是一個數據類型所能存放的記憶體地址的屬性(Alignment is a property of a memory address)。這個屬性是一個無符號整數,並且這個整數必須是2的N次方(1、2、4、8、……、1024、……)。當我們說,一個數據類型的記憶體對齊為8時,意思就是指這個數據類型所定義出來的所有變數,其記憶體地址都是8的倍數。當一個基本數據類型(fundamental types)的對齊屬性,和這個數據類型的大小相等時,這種對齊方式稱作自然對齊(naturally aligned)。比如,一個4位元組大小的int型數據,預設情況下它的位元組對齊也是4。

為什麼我們需要記憶體對齊?

這是因為,並不是每一個硬體平臺都能夠隨便訪問任意位置的記憶體的。

微軟的MSDN里有這樣一段話:

Many CPUs, such as those based on Alpha, IA-64, MIPS, and SuperH architectures, refuse to read misaligned data. When a program requests that one of these CPUs access data that is not aligned, the CPU enters an exception state and notifies the software that it cannot continue. On ARM, MIPS, and SH device platforms, for example, the operating system default is to give the application an exception notification when a misaligned access is requested.

大意是說,有不少平臺的CPU,比如Alpha、IA-64、MIPS還有SuperH架構,若讀取的數據是未對齊的(比如一個4位元組的int在一個奇數記憶體地址上),將拒絕訪問,或拋出硬體異常。

另外,在維基百科里也記載著如下內容:

Data alignment means putting the data at a memory offset equal to some multiple of the word size, which increases the system's performance due to the way the CPU handles memory.

意思是,考慮到CPU處理記憶體的方式(32位的x86 CPU,一個時鐘周期可以讀取4個連續的記憶體單元,即4位元組),使用位元組對齊將會提高系統的性能(也就是CPU讀取記憶體數據的效率。比如你一個int放在奇數記憶體位置上,想把這4個位元組讀出來,32位CPU就需要兩次。但對齊之後一次就可以了)。


  • 需要位元組對齊的根本原因在於CPU訪問數據的效率問題。假設上面整型變數的地址不是自然對齊,比如為0x00000002,則CPU如果取它的值的話需要訪問兩次記憶體,第一次取從0x00000002-0x00000003的一個short,第二次取從0x00000004-0x00000005的一個short然後組合得到所要的數據,如果變數在0x00000003地址上的話則要訪問三次記憶體,第一次為char,第二次為short,第三次為char,然後組合得到整型數據。
  • 而如果變數在自然對齊位置上,則只要一次就可以取出數據。一些系統對對齊要求非常嚴格,比如sparc系統,如果取未對齊的數據會發生錯誤,而在x86上就不會出現錯誤,只是效率下降。
  • 各個硬體平臺對存儲空間的處理上有很大的不同。一些平臺對某些特定類型的數據只能從某些特定地址開始存取。
  • 比如有些架構的CPU在訪問一個沒有進行對齊的變數的時候會發生錯誤,那麼在這種架構下編程必須保證位元組對齊,但其他平臺可能沒有這種情況,但是最常見的是如果不按照適合其平臺要求對數據存放進行對齊,會在存取效率上帶來損失。
  • 比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設為32位系統)如果存放在偶地址開始的地方,那麼一個讀周期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀周期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit數據。顯然在讀取效率上下降很多。
  • 另外位元組對齊的作用不僅是==便於cpu快速訪問==,同時合理的利用位元組對齊可以==有效地節省存儲空間==。
  • 也即CPU一次訪問時,要麼讀0x01~0x04,要麼讀0x05~0x08…硬體不支持一次訪問就讀到0x02~0x05
  • 例:如果0x02~0x05存了一個int,讀取這個int就需要先讀0x01~0x04,留下0x02~0x04的內容,再讀0x05~0x08,留下0x05的內容,兩部分拼接起來才能得到那個int的值,這樣讀一個int就要兩次記憶體訪問,效率就低了


個人公眾號

匠心零度公眾號.jpg

參考:
https://www.2cto.com/kf/201407/319682.html
http://blog.csdn.net/qq_25077833/article/details/53454958


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 核心:浮動元素會脫離文檔流並向左/向右移動,直到碰到父元素或者另外一個浮動元素。 float :left 向左浮動 right 向右浮動 none (預設) inherit 繼承父元素 float效果 原效果圖 換張圖.....因為我突然發現一個問題,用這張圖不好解釋........ 原圖 代碼 然 ...
  • 一、函數的調用方式 1.作為函數,一種直接易懂的方式(即函數調用模式)。 2.作為方法,方法是連接在對象上的,被這個對象調用,這種形式就是面向對象編程。 3.作為構造器,在構造的過程中一個新的對象被創建出來。 4.經由函數的apply或者call方法。 二、函數參數 1.傳入參數 (1)傳入變數多於 ...
  • 1. 創建對象的幾種方式 ...
  • JSONP:一種非官方跨域數據交互協議 JSONP怎麼產生的 JSONP的原理 看上面的來源加以理解 上面說過了,script是不受跨域影響的 那麼我們可以在我們代碼中引用B伺服器的文件 在B伺服器端demoResult.aspx會根據我們傳的callback參數jsonpCallback自動返回數 ...
  • - 是express框架下的一個方法,可以根據請求路徑名查找某個文件下文件名字和路徑名相同的文件 - 3.X裡面有20多個中間件,但是在4.X裡面 只保留了express.static - 語法 express.static('/設置一下請求路徑/路徑名','要被查找文件夾的絕對路徑') 請求路徑後 ...
  • 前端面試經常會問關於原型鏈的知識,今天我總結了一下關於原型鏈的內容,希望對廣大小白一點點參考~ 什麼是原型? 在 js 中,對象都有 __proto__ 屬性, 就是指這個對象的原型,如果構造函數 A 實例化一個對象 B,那麼 A.prototype 就是 B 的原型。也就是: 什麼是原型鏈? 介紹 ...
  • 效果圖: ...
  • - 安裝 body-parser模塊- npm install body-parser -S- 調用- let bodyParser=require('body-parser');- 設置中間件- app.use(bodyParser.urlencoded({extended:true}));- 判 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...