JVM菜鳥進階高手之路十(基礎知識開場白)

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

轉載請註明原創出處,謝謝! 最近沒有什麼實戰,準備把JVM知識梳理一遍,先以開發人員的交流來談談jvm這塊的知識以及重要性,依稀記得2、3年前用solr的時候老是經常oom,提到oom大家應該都不陌生,那個時候也並沒有從根本解決oom,由於對jvm不熟悉,只是去百度,到處都是配置jvm參數的,那個時 ...


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

最近沒有什麼實戰,準備把JVM知識梳理一遍,先以開發人員的交流來談談jvm這塊的知識以及重要性,依稀記得2、3年前用solr的時候老是經常oom,提到oom大家應該都不陌生,那個時候也並沒有從根本解決oom,由於對jvm不熟悉,只是去百度,到處都是配置jvm參數的,那個時候啥不懂,直接粘貼,但是並沒有解決問題,通過這個就告訴我們作為開發人員也需要對jvm很熟悉才行,問題來了,很多人會說我的代碼並沒有出現oom啊,不需要關註啊,因為不理解不知道重要性,可以回頭看看的我的JVM菜鳥進階高手之路一到九篇系列,可能很多人說還沒有到那麼高級,不需要理解,我也告訴你也是不對的,且聽我慢慢道來。

談到jvm首先需要談的是,JAVA虛擬機規範,這個就類似jdbc規範一樣,定義了一些規範,oracle有oracle的實現,mysql有mysql的實現,JAVA虛擬機規範也一樣,java虛擬機有很多,IBM、Apache Harmony等,每個都有些細節不一樣,但是大體符合JAVA虛擬機規範的,由於Oracle收購SUN之後,Oralce主要有JRockit和Hotspot虛擬機了,後來將其進行整合了,不然維護兩套麻煩,就和原來的struts1和struts2一樣,Oralce主要是以Hotspot來的,把JRockit裡面的一些優點也慢慢加入到其中。目前市面上Hotspot占用率是最高的,一般說到JAVA虛擬機基本都是Hotspot虛擬機。JAVA8虛擬機規範地址:http://docs.oracle.com/javase/specs/jvms/se8/html/index.html,按照道理應該去閱讀閱讀的,雖然java語言與java虛擬機有密切的關係,但是兩者是完全不同的內容,像Scala、Clojure、Groovy等語言都是跑在JAVA虛擬機上面的,可以產生各種各樣的跨平臺語言,除了語言特性不一樣,他們可以共用JAVA虛擬機帶來的跨平臺性、垃圾回收器、以及即使編譯(看到這裡都應該明白這些的JAVA虛擬機擁有的不是java語言規範定義的,java語言規範地址:http://docs.oracle.com/javase/specs/jls/se8/html/index.html),稍微解釋下為什麼用JAVA虛擬機就可以做到跨平臺呢?依稀記得當時剛剛學習java的時候有句口號“一次編譯,到處運行。”Java程式理想上,並不理會真正執行哪個平臺,只要知道如何執行於JVM就可以了,至於JVM實際上如何與底層平臺溝通,那是JVM自己的事。由於JVM實際上相當於Java程式的操作系統,JVM就負責了Java程式的各種資源管理。

我們要記住兩點:

  • JVM就是Java程式的操作系統,JVM的可執行文件就是.class文件。
  • Java虛擬機屏蔽了操作系統之間的差異,但是不同的系統使用的虛擬機不同。

與其他語言相比,Java程式能夠做到“編譯一次,到處運行”,可見它的跨平臺性非常強。其實JVM就是在操作系統層面有抽象了一層虛擬機,這樣的好處可以屏蔽底層細節,有每個具體的平臺的虛擬機實現即可,但是對外提供的是一致的(比如windows需要安裝windows版的jdk,linux需要安裝linux版的jdk就是這個原因,jvm虛擬機幫我們屏蔽到了底層的細節)。

一直有一個疑惑,Oracle的jdk和OpenJDK到底有什麼關係呢?

Oracle/Sun JDK與OpenJDK的區別和聯繫如下: - OpenJDK原是SunMicrosystems公司為Java平臺構建的Java開發環境(JDK)的開源版本,完全自由,開放源碼。Sun Microsystems公司在2006年的JavaOne大會上稱將對Java開放源代碼,於2009年4月15日正式發佈OpenJDK。甲骨文在 2010 年收購SunMicrosystem之後接管了這個項目。

  • oracle/Sun JDK裡面包含的JVM是HotSpotVM,HotSpot VM只有非常非常少量的功能沒有在OpenJDK里,那部分在Oracle內部的代碼庫里。這些私有部分都不涉及JVM的核心功能。所以說,Oracle/Sun JDK與OpenJDK其實使用的是同一個代碼庫。
  • 從一個Oracle內部員工的角度來看,當他要構建OracleJDK時,他同樣需要先從http://hg.openjdk.java.NET簽出OpenJDK,然後從Oracle內部的代碼庫簽出私有的部分,放在OpenJDK代碼下的一個特定目錄里,然後構建。值得註意的是,Oracle JDK只發佈二進位安裝包,而OpenJDK只發佈源碼。

知道關係之後,其實很多就釋然了,其實阿裡的jdk就是基於OpenJDK定製的,所以看看OpenJDK對理解JVM很有幫助的,OpenJDK的github地址如下:https://github.com/dmlloyd/openjdk,既然都看見了OpenJDK的源碼,那麼是否有興趣編譯編譯。

用final可以提高性能,為什麼呢?

依稀記得以前老師說,用final可以提高性能,為什麼呢?由於類的載入機制,關於一個*.class如何載入進來,如何一系列的操作後續會進行介紹,由於類的載入機制會提到一些熱替換,熱載入,以及閱讀tomcat源碼的時候可以瞭解到他是怎麼處理載入的,由於final常量在準備階段就初始化了,而並不是在初始化結點處理的,所以可以提高程式相應效率。
申明為final的情況:

  • 不需要重新賦值的變數,包括類屬性、局部變數。
  • 對象參數前面加final,表示不允許修改引用的指向。
  • 類的方法不可以被重寫。

由於final關鍵字,在併發鎖的時候,不可變的一些情況鎖是無效的

比如鎖一個Integer、Double、String等是不行的,你說這些你對JVM不瞭解能行嗎?

JAVA虛擬機對各各數據類型的表示,所以引入了關於,原碼,補碼,反碼等概念,為什麼需要補碼呢?

補碼的好處:

  • 使用補碼可以沒有任何歧義的表示0。
  • 補碼可以很好的參與二進位的運算,補碼相加符號位參與運算, 這樣就簡單很多了。那就可以明白為什麼數據溢出的概念了,經常看到

    byte a=(byte)(127+1); 
    System.out.println(a);

如果不瞭解JVM怎麼能懂,還有兩個值相同的Integer型值進行==比較時:

Integer a=125;
 Integer b=125;
 Integer d=300;
 Integer c=300; 
System.out.println(c==d); 
System.out.println(a==b);

運行結果為falsetrue?為什麼呢? 查看源碼: 這兒的IntegerCache有一個靜態的Integer數組,在類載入時就將-128 到 127 的Integer對象創建了,並保存在cache數組中, 一旦程式調用valueOf 方法,如果i的值是在-128 到 127 之間就直接在cache緩存數組中去取Integer對象,超出 -128 ~ +127 範圍的數字就要即時構建新的Integer對象,可以通過JVM參數 -XX:AutoBoxCacheMax來進行調整。 那麼== 和equals的區別,== 是進行地址及值比較,無法對==操作符進行重載,而對於equals方法,Integer裡面的equals方法 重寫了Object的equals方法,所以,相同類型的包裝類對象直接的值比較全部使用equals方法比較,並且能用基本數據類型 就應該用基本數據類型,這些你不瞭解JVM你那裡知道呢?

根據IEEE754定義的浮點數的格式,所以涉及到錢的小數類型必須使用BigDecimal,禁止使用float和double,為什麼呢?

不懂JVM可以?後續會講。

慎用Object的clone方法拷貝對象,深拷貝,淺拷貝。

你不瞭解jvm模型咋知道呢?還有Object的finalize你不瞭解JVM怎麼理解呢?

對於String的一些操作,String的文章最多。+運算符號

String str = "start";
 for(int i=0; i<100; i++){ 
     str = str + "hello"; 
}

反編譯出的位元組碼文件顯示每次迴圈都會new出一個StringBuilder對象,然後進行append操作,最後通過toString方法返回String對象,造成記憶體資源浪費。

其他

HashMap、ArrayList、StringBuilder等的擴容機制,會浪費空間以及性能,特別在併發情況下麵可能會死鎖,後續分享hashMap的cpu 100%情況,所以集合初始化時,儘量指定集合初始值大小,你不瞭解jvm怎麼可以呢?還有很多框架,netty等對外記憶體(堆外空間),多線程相關ThreadLocal等,還有鎖在java虛擬機中的實現優化,你不瞭解怎麼可以呢?
今天僅僅是開場白,後續會有系列基礎知識文章出來。大家一起進步。


個人公眾號

匠心零度公眾號.jpg


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

-Advertisement-
Play Games
更多相關文章
  • 最近在學習Oracle的統計信息這一塊,收集統計信息的方法如下: DBMS_STATS.GATHER_TABLE_STATS ( ownname VARCHAR2, 所有者名字 tabname VARCHAR2, 表名 partname VARCHAR2 DEFAULT NULL, 要分析的分區名 ...
  • 將所學知識整理一下,備忘。 1. Hdfs (v 2.7.3) 1.1.啟動集群 註:這個啟動腳本是通過ssh對多個節點的namenode、datanode、journalnode以及zkfc進程進行批量啟動的。 1.2.啟動NameNode 1.3.啟動DataNode 1.4.停止集群 1.5. ...
  • 一.Oracle的支持數據類型 1.字元串類型 char 固定長度(定義時即已確定長度,空餘位置被補全),最大長度255,如 name char(10),'中'會占用10個長度; varchar2 長度不固定,根據實際情況占用,空餘被放棄,最大長度3999,如 name varchar2(10),'... ...
  • SQL概念:結構化查詢語言(SQL = Structured Query Language),也是一種編程語言(資料庫查詢和程式設計語言),可以用於數據的存取及查詢,更新,管理關係型資料庫系統ps: 不同資料庫系統之間的SQL不能完全相互通用;分類針對操作的對象不同,可以分成不同語言1: 數據操作( ...
  • 原創,轉發請註明出處。 MapReduce是hadoop這隻大象的核心,Hadoop 中,數據處理核心就是 MapReduce 程式設計模型。一個Map/Reduce 作業(job) 通常會把輸入的數據集切分為若幹獨立的數據塊,由 map任務(task)以完全並行的方式處理它們。框架會對map的輸出 ...
  • Spark對很多種文件格式的讀取和保存方式都很簡單。Spark會根據文件擴展名選擇對應的處理方式。 Spark支持的一些常見文件格式如下: 1、文本文件 使用文件路徑作為參數調用SparkContext中的textFile()函數,就可以讀取一個文本文件。也可以指定minPartitions控制分區 ...
  • 一.Oracle資料庫的安裝(安裝在虛擬機的xp系統里) 1.安裝虛擬機 2.虛擬機內安裝xp系統,以下步驟在虛擬機內進行 3.雙擊setup.exe,在出現的界面中設置口令,及確認口令(此口令即為system賬號的密碼),點擊下一步 4.先決條件檢查,將"用戶已驗證前面的覆選框打勾,下一步 5.概... ...
  • 如果是重覆安裝,首先需要清除已經存在的軟體安裝記錄(首次安裝只需執行紅色部分): rm -fr /usr/local/bin/*oraenv rm -fr /usr/local/bin/dbhome rm -fr /usr/tmp/.oracle rm -fr /tmp/.Oracle rm -fr... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...