Java進階1-JVM虛擬機 JVM在字節碼上的使用方法
1. JVM簡述
(資料圖片)
JVM是Java Virtual Machine的縮寫。它是一種基于計算設備的規范,是一臺虛擬機,即虛構的計算機。 JVM屏蔽了具體操作系統平臺的信息(顯然,就像是我們在電腦上開了個虛擬機一樣),當然,JVM執行字節碼時實際上還是要解釋成具體操作平臺的機器指令的。 如類加載機制、運行時數據區、垃圾回收機制等; 官網:https://www.oracle.com/java/technologies/javase/vmoptions-jsp.html
2. 字節碼
2.1 字節碼由來
Java 所有的指令有 200 個左右,一個字節( 8 位)可以存儲 256 種不同的指令信息,一個這樣的字節稱為字節碼( Bytecode )
JVM 將字節碼解釋執行,屏蔽對底層操作系統的依賴,JVM也可以將字節碼編譯執行,如果是熱點代碼,會通過JIT 動態地編譯為機器碼,提高執行效率
JVM在字節碼上也設計了一套操作碼助記符,使用特殊單詞來標記這些數字。 加載或存儲指令 、運算指令、類型轉換指令、對象創建與訪問指令、操作棧管理指令、方法調用與返回指令。
2.2 源碼轉化成字節碼
詞法解析是通過空格分隔出單詞 、操作符、控制符等信息 , 將其形成 token 信息流 ,傳遞給語法解析器。 在語法解析時,把詞法解析得到的 token 信息流按照 Java 語法規則組裝成一棵語法樹 , 如圖 4-2 虛線框所示。 在語義分析階段 , 需要檢查關鍵字的使用是否合理、類型是否匹配、作用域是否正確等。 當語義分析完成之后,即可生成字節碼。
2.2 執行三種模式
字節碼必須通過類加載過程加載到 JVM 環境后,才可以執行。執行有三種模式:第一,解釋執行;第二,JIT 編譯執行;第三, JIT 編譯與解釋混合執行(主流 JVM默認執行模式)?;旌蠄绦心J降膬瀯菰谟诮忉屍髟趩訒r先解釋執行,省去編譯時間。隨著時間推進 , JVM 通過熱點代碼統計分析 , 識別高頻的方法調用、循環體、公共模塊等,基于強大的 JlT 動態編譯技術,將熱點代碼轉換成機器碼,直接交給 CPU執行。 JIT 的作用是將 Java 字節碼動態地編譯成可以直接發送給處理器指令執行的機器碼。簡要流程如圖 4-3 所示。 注意解釋執行與編譯執行在線上環境微妙的辯證關系。機器在熱機狀態可以承受的負載要大于冷機狀態(剛啟動時 ),如果以熱機狀態時的流量進行切流 , 可能使處于冷機狀態的服務器因無法承載流量而假死。 剛啟動的 JVM 均是解釋執行,還沒有進行熱點代碼統計和 JIT 動態編譯。
3. 類加載過程
3.1 類加載流程
1、Load加載(讀取二進制流轉特定數據結構) 2、Link鏈接( 驗證-詳細校驗如類型、常量、靜態變量等。 準備-為靜態變量分配內存。 解析-確保類與類之間的相互引用正確性,完成內存結構布局) 3、Init初始化(執行類構造器完成類的初始化) 4、解析執行直接給CPU、JIT動態編譯機器碼再給CPU 類加載是一個將 . class 字節碼文件實例化成 Class 對象并進行相關初始化的過程。 全小寫的 class 是關鍵字,用來定義類,而首字母大寫的 Class ,它是所有 class 的類。** 問題:**為什么這個抽象還是另外一個類 Class 的對象? 示例代碼如下:
/** * @author cmy * @version 1.0 * @date 2022/6/29 0029 13:43 * @description 類加載過程測試 */public class ClassTest {//數組類型有一個魔法屬性:length來獲取數組長度 private static int[] array=new int[3]; private static int length=array.length; //任何小寫class定義的類,也有一個魔法屬性:class,來獲取此類的大寫Class類對象 private static Classone=One.class; private static Classanother=Another.class; public static void main(String[] args) throws Exception {//通過newInstance方法創建One和 Another的類對象(第1處) One oneObject=one.newInstance(); oneObject.call(); Another anotherObject=another.newInstance(); anotherObject.speak(); //通過one這個大寫的Class對象,反射方式獲取私有成員屬性對象Field(第2處) Field privateFieldInOne = one.getDeclaredField("inner"); //設置私有對象可以訪問和修改(第3處) privateFieldInOne.setAccessible(true); privateFieldInOne.set(oneObject,"world changed"); //成功修改類的私有屬性inner變量值為world changed. System.out.println(oneObject.getInner()); }}class One{private String inner="time files."; public void call(){System.out.println("hello world"); } public String getInner(){return inner; }}class Another{public void speak(){System.out.println("easy coding"); }}
第1處說明new 是強類型校驗 , 可以調用任何構造方法 , 在使用new 操作的時候,這個類可以沒有被加載過。 Class 類下的 newInstance是弱類型,只能調用無參數構造方法,如果沒有默認構造方法,就拋出InstantiationException 異常,如果此構造方法沒有權限訪問,則拋出IllegalAccessException 異常。 第2處說明使用類似的方式獲取其他聲明 , 如注解、方法等,如圖4.5所示。 第3處說明問題:private 成員在類外是否可以修改?通過 setAccessible(true) 操作,即可使用大寫 C lass 類的 set 方法修改其值。
3.2 類加載器實現機制
/** * 查看本地類加載器的方式如下 */ //正在使用得類加載器sun.misc.Launcher$AppClassLoader@18b4aac2 ClassLoader c = One.class.getClassLoader(); //AppClassLoader的父類加載器是ExtensionClassLoader JDK1.9之前 ClassLoader c1 = c.getParent(); //ExtClassLoader父類加載器(最高一層)Bootstrap C++實現 返回null ClassLoader c2 = c1.getParent(); System.out.println(c); System.out.println(c1); System.out.println(c2);
低層次的當前類加載器,不能覆蓋更高層次類加載器已經加載的類。 如圖 4-6 所示,左側綠色箭頭向上逐級詢問是否已加載此類,直至 Bootstrap ClassLoader ,然后向下逐級嘗試是否能夠加載此類,如果都加載不了,則通知發起加載請求的當前類加載器 ,準予加載。 通過如下代碼可以查看 Bootstrap 所有已經加載的類庫:
/** * 通過如下代碼可以查看BootstrapClassLoader所有已經加載的類庫: */ URL[] urLs = Launcher.getBootstrapClassPath().getURLs(); for (java.net.URL url:urLs) {System.out.println(url.toExternalForm()); }
在JVM中增加如下啟動參數 , 則能通過 Class.forName 正常讀取到指定類 , 說明此參數可以增加Bootstrap 的類加載路徑:
- Xbootclasspath/a:/Users/yangguanbao/book/easyCoding/byJdk11/src
如果想在啟動時觀察加載了哪個jar包中的哪個類 ,可以增加-XX:+TraceClassLoading參數
- XX:+TraceClassLoading
3.3 自定義類加載器
學習類加載器的實現機制后 , 雙親委派模型并非強制模型, 用戶可以自定義類加載器 。問題:在什么情況下需要自定義類加載器呢? ** ** 隔離加載類、修改類加載方式、擴展加載源、防止源碼泄露。
實現自定義類加載器的步驟,繼承ClassLoader,重寫 findClass()方法,調用defineClass()方法。一個簡單的類加載器實現的示例代碼如下:
/** * @author cmy * @version 1.0 * @date 2022/6/29 0029 15:34 * @description 自定義類加載器 * * 自定義類加載器步驟: * 繼承ClassLoader * 重寫findClass()方法 * 調用defineClass()方法 */public class CustomClassLoader extends ClassLoader {private String classpath; public CustomClassLoader(String classpath) {this.classpath = classpath; } @Override protected Class findClass(String name) throws ClassNotFoundException {try {byte[] bytes = getClassFromCustomPath(name); return defineClass(name, bytes, 0, bytes.length); } catch (IOException e) {e.printStackTrace(); throw new ClassNotFoundException(); } } private byte[] getClassFromCustomPath(String name) throws IOException {//從自定義路徑中加載指定類 FileInputStream fis = new FileInputStream(classpath + File.separator + name.replace(".", File.separator).concat(".class")); byte[] bytes = new byte[fis.available()]; fis.read(bytes); fis.close(); return bytes; } public static void main(String[] args) {CustomClassLoader customClassLoader = new CustomClassLoader("F:\\IDEA2022\\workmenu\\SoftwareTools\\src\\main\\java"); try {Class clazz = customClassLoader.loadClass("Test"); //調用的靜態方法 clazz.getDeclaredMethod("say").invoke(clazz); Object o = clazz.newInstance(); Method print = clazz.getDeclaredMethod("print", String.class); print.invoke(o, "調用的對象方法"); //自定義類加載器 System.out.println(clazz.getClassLoader()); //AppClassLoader System.out.println(clazz.getClassLoader().getParent()); //ExtClassLoader System.out.println(clazz.getClassLoader().getParent().getParent()); //BootstrapLoader System.out.println(clazz.getClassLoader().getParent().getParent().getParent()); }catch (Exception e){e.printStackTrace(); } }}//https://blog.csdn.net/weixin_42759726/article/details/114030153
//javac編譯后,記得刪除Test.java比較路徑尋找和Test.class沖突public class Test {public static void say() {System.out.println("this is a static method!"); } public void print(String s) {System.out.println("printing:"+s); }}
按某種規則 jar 包的版本被統←指定 ,導致某些類存在包路徑、類名相同 的情況 , 就會引起類沖突 ,導致應用程序出現異常。主流的容器類框架都會自定義類加載器,實現不同中間件之間的類隔離 , 有效避免了類沖突。
4. 內存布局(運行時數據區域)
前面回顧連接
在類加載過程第二步Link鏈接的解析階段,解析類和方法確保類與類之間的相互引用正確性,完成內存 結構布局。
4.1 內存布局簡介
Java 程序在運行時,會為 JVM 單獨劃出一塊內存區域,而這塊內存區域又可以再次劃分出一塊運行時數據區,運行時數據區域大致可以分為五個部分:
4.2 Heap堆區
**Heap堆區作用:**Heap 是 OOM 故障最主要的發源地 , 它存儲著幾乎所有的實例對象, 堆由垃圾收集器自動回收 , 堆區由各子線程共享使用。 堆的內存空間既可以固定大小 , 也可以在運行時動態地調整。
比如 -Xms256M -Xmxl024M ,其中 -X 表示它是 JVM 運行參數, ms 是 memory start 的簡 稱, mx 是 memory max 的簡稱,分別代表最小堆容量和最大堆容量。 一般最大和最小一樣。避免在GC后調整堆大小時帶來的額外壓力。
堆分成兩大塊:新生代和老年代。新生代= 1 個 Eden 區+ 2 個Survivor 區。
當 Eden區裝填滿的時候 , 會觸發 Young Garbage Collection , 即 YGC。垃圾回收的時候 , 在 Eden 區實現清除策略 , 沒有被引用的對象則直接回收。依然存活的對象會被移送到 Survivor 區。
**問題:**Survivor 區分為 S0和 S1兩塊內存空間 , 送到哪塊空間呢? 每次 YGC 的時候, 它們將存活的對象復制到未使用的那塊空間,然后將當前正在使用的空間完全清除 , 交換兩塊空間的使用狀態。
**問題:**如何防止對象沒有進取心? 每個對象都有一個計數器,每次 YGC 都會加1。 -XX:MaxTenuringThreshold 參數能配置計數器的值到達某個閥值的時候 , 對象從新生代晉升至老年代。
對象分配與簡要GC流程圖如圖4-9所示。 圖 的 中,如果 Survivor 區無法放下,或者超大對象的鬧值超過上限,則嘗試在老年代中進行分配 ; 如果老年代也無法放下,則會觸發 Full Garbage Collection , 即FGC。如果依然無法放下, 則拋出 OOM。堆內存出現 OOM 的概率是所有內存耗盡異常中最高的。出錯時的堆內信息對解決問題非常有幫助 , 所以給JVM設置運行參數 -XX:+HeapDumpOnOutOfMemoryError,讓JVM遇到OOM 異常時能輸出堆內信息,特別是對相隔數月才出現的 OOM 異常尤為重要。
4.3 Metaspace (元空間)
元空間作用:存儲常量池、方法元信息、類元信息。字符串常量String存在堆內存。
元空間發展:源碼解析和示例代碼基本采用 JDK11版本, JVM則為 Hotspot。在 JDK7 及之前的版本中,只有 Hotspot才有 Perm 區,譯為永久代 , 它在啟動時固定大小,很難進行調優。動態加載類過多,容易產生 Perm 區的 OOM。為了解決Perm 區的 OOM, 需要設定運行參數 -XX:MaxPermSize= 1280m。
永久代在垃圾回收過程中還存在諸多問題。 JDK8 使用元空間替換永久代。在 JDK8 及以上版本中,設定 MaxPermSize 參數, JVM在啟動時并不會報錯。
區別于永久代 , 元空間在本地內存中分配。在 JDK8 里, Perm 區 中的所有內容 中字符串常量移至堆內存,其他內容包括類元信息、字段、靜態屬性、方法、常量等 都移動至無空間內。
圖 4-10 中顯示在常量池中的 String, 其實際對象是被保存在堆內存中的。
4.4 JVM Stack (虛擬機棧)
**虛擬機棧作用:描述JAVA方法執行的內存區域。**方法調用到執行完成~入棧到出棧的過程。棧頂的幀稱為棧幀,正在執行的方法稱為當前方法,棧幀是方法運行的基本結構。StackOverflowError表示請求的棧溢出,內存耗盡。 棧幀在整個 JVM 體系中的地位頗高, 包括局部變量表、操作棧、動態連接、方法返回地址等。
1 局部變量表2 操作棧
public int simpleMethod(){//將常量13壓入操作棧、保存到局部變量表的slot_1中 int x=13; //將常量14壓入操作棧、保存到局部變量表的slot_2中 int y=14; //將slot_1元素壓入操作棧,將slot_2元素壓入操作棧, //再取出來到CPU中加法,并壓回操作棧,把棧頂結果保存到局部變量表的slot_3中 int z= x+y; //返回棧頂元素值 return z;}
** 3 動態鏈接** 每個枝幀中包含一個在常量池中對當前方法的引用 , 目的是支持方法調用過程的動態連接。 4 方法返回地址
4.5 Native Method Stacks (本地方法棧)
本地方法棧作用:虛擬機?!爸鲀?”, 而本地方法?!爸魍狻?。本地方法棧為 Native 方法服務。本地方法可以通過 JNI ( Java Native Int rface )來訪問虛擬機運行時的數據區 ,甚至可以調用寄存器,具有和 JVM 相同的能力和權限。對于內存 不足的情況 本地方法枝還是會拋出 native heap OutOfMemory。
4.6 Program Counter Register(程序計數寄存器)
程序計數寄存器作用:CPU 只有把數據裝載到寄存器才能夠運行。保證在多線程并發執行過程中,保證分毫無差。**問題:**由于CPU時間片輪限制,眾多線程在并發執行過程中,導致經常中斷或恢復,如何保證分毫無差呢? 每個線程在創建后,都會產生 自己的程序計數器和棧幀,程序計數器用來存放執行指令的偏移量和行號指示器等, 線程執行或恢復都要依賴程序計數器。程序計數器在各個線程之間互不影響,此區域 也不會發生內存溢出異常。
4.7 運行時數據區域總結
1 Heap堆區作用:Heap 是 OOM 故障最主要的發源地 ,它存儲著幾乎所有的實例對象。堆由垃圾收集器自動回收 , 堆區由各子線程共享使用。 堆的內存空間既可以固定大小 , 也可以在運行時動態地調整。 2 元空間作用:存儲常量池、方法元信息、類元信息。字符串常量String存在堆內存。3 虛擬機棧作用:描述JAVA方法執行的內存區域。方法調用到執行完成~入棧到出棧的過程。棧頂的幀稱為棧幀,正在執行的方法稱為當前方法,棧幀是方法運行的基本結構。StackOverflowError表示請求的棧溢出,內存耗盡。 4 本地方法棧作用:虛擬機?!爸鲀?”, 而本地方法?!爸魍狻?。本地方法棧為 Native 方法服務。本地方法可以通過 JNI ( Java Native Int rface )來訪問虛擬機運行時的數據區 ,甚至可以調用寄存器。 5 程序計數寄存器作用:CPU 只有把數據裝載到寄存器才能夠運行。保證在多線程并發執行過程中,保證分毫無差。每個線程在創建后,都會產生 自己的程序計數器和棧幀,程序計數器用來存放執行指令的偏移量和行號指示器等。
5. 對象實例化
Java 是面向對象的靜態強類型語言,根據某個類聲明一個引用變量指向被創建的對象。 問題:在實例化對象的過程中,JVM會發生什么化學反應?
5.1 從字節碼的進行分析
1、NEW類加載 2、DUP棧頂復制引用變量 3、INVOKESPECIAL初始化
5.2 從執行步驟的角度分析
1、確認類元信息是否存在 2、分配對象內存 3、設定默認值 4、設置對象頭 5、執行init方法
6. 垃圾回收
垃圾回收( Garbage Collection, GC )。垃圾回收的主要目的是清除不再使用的對象,自動釋放內存。
6.1 對象是否存活的標準
問題:GC 是如何判斷對象是否可以被回收的呢?為了判斷對象是否存活 , JVM 引人了GC Roots。某個失去任何引用的對象,或者兩個互相環島狀循環引用的對象等,可以直接回收。 問題:什么對象可以作為 GC Roots 呢?比如類靜態屬性中引用的對象、常量引用的對象、虛擬機棧中尋引用的對象、本地方法棧中引用的對象等。
6.2 垃圾回收的相關算法
“標記-清除算法”。
該算法從GC Roots出發,依次標記有引用關系的對象,將沒有被標記的對象清除。此算法會帶來大量的空間碎片,要分配較大連續空間容易出現FGC。
“標記-整理算法”。
該算法從GC Roots出現標記存活對象,然后將存活對象整理導內存空間的一端,形成已使用的連續空間,最后把已使用空間外的部分全部清理掉。
“Mark-Copy算法”(主流YGC算法新生代垃圾回收)。也稱標記-復制
為了并行地標記和整理,將空間分為兩塊,每次只激活一塊。垃圾回收時只需要把存活對象復制到另一塊未激活空間,將未激活空間標記為已激活,將已激活空間標記為未激活,然后清除原空間對象,如此反復置換清除。每次只使用堆區一塊Eden區和Survior區,減少了內存空間的浪費。
6.2 垃圾回收器
垃圾回收器( Garbage Collector )是實現垃圾回收算法并應用在 JVM 環境中的內存管理模塊 。
Serial 回收器
Serial 回收器是一個主要應用于 YGC 的垃圾回收器,采用串行單線程的方式完成 GC 任務。其中"Stop The World"簡稱STW,即垃圾回收的某個階段會暫停整個應用程序的執行。標記-復制算法YGC
CMS 回收器
CMS 回收器 (Concurrent Mark Sweep Collector) 是回收停頓時間比較短、目前比較常用的垃圾回收器,采用"標記-清除算法"。 通過初始標記(Initial Mark) 、并發標記(Concurrent Mark )、重新標記(Remark)、并發清除(Concurrent Sweep)四個步驟完成垃圾回收工作。
G1回收器
Hotspot 在 JDK7 中 推出了新一代 G1 ( Garbage-First Garbage Collector ) 垃圾回收 ,通過去-XX:+UseG1GC參數啟用。G1采用"Mark-Copy算法"。 GI 將 Java 堆空間分割成了若干相同大小的 區域,即 region ,包括 Eden 、Survivor 、 Old 、 Humongous 四種類型。
7. JVM監控工具
7.1 jconsole
Jconsole(Java Monitoring and Management Console)是從 java5 開始,在 JD K中自帶的 java 監控和管理控制臺,用于對 JVM 中內存,線程和類等的監控,是一個基于 JMX(java management extensions)的 GUI 性能監測工具。
7.2 VisualVM
VisualVM(All-in-One Java Troubleshooting Tool)是功能最強大的運行監視和故障處理程序之一,曾經在很長一段時間內是 Oracle 官方主力發展的虛擬機故障處理工具。
8. JVM 調優選擇
8.1 選擇合適的垃圾回收器
CPU 單核:那么毫無疑問 Serial 垃圾收集器是你唯一的選擇;CPU 多核:關注吞吐量 ,那么選擇 PS+PO 組合;JDK8默認CPU 多核:關注用戶停頓時間,JDK 版本 1.6 或者 1.7,那么選擇 CMS;CPU 多核:關注用戶停頓時間,JDK1.8 及以上,JVM 可用內存 6G 以上,那么選擇 G1。
參數配置:
//設置Serial垃圾收集器(新生代)開啟:-XX:+UseSerialGC//設置PS+PO,新生代使用功能Parallel Scavenge 老年代將會使用Parallel Old收集器開啟 -XX:+UseParallelOldGC//CMS垃圾收集器(老年代)開啟 -XX:+UseConcMarkSweepGC//設置G1垃圾收集器 開啟 -XX:+UseG1GC
8.2 調整內存大小
現象:垃圾收集頻率非常頻繁。 原因:如果內存太小,就會導致頻繁的需要進行垃圾收集才能釋放出足夠的空間來創建新的對象,所以增加堆內存大小的效果是非常顯而易見的。 注意:如果垃圾收集次數非常頻繁,但是每次能回收的對象非常少,那么這個時候并非內存太小,而可能是內存泄露導致對象無法回收,從而造成頻繁 GC。 參數配置:
//設置堆初始值 指令1:-Xms2g 指令2:-XX:InitialHeapSize=2048m //設置堆區最大值 指令1:`-Xmx2g` 指令2: -XX:MaxHeapSize=2048m //新生代內存配置 指令1:-Xmn512m 指令2:-XX:MaxNewSize=512m
8.3 設置符合預期的停頓時間
現象:程序間接性的卡頓 原因:如果沒有確切的停頓時間設定,垃圾收集器以吞吐量為主,那么垃圾收集時間就會不穩定。 注意:不要設置不切實際的停頓時間,單次時間越短也意味著需要更多的 GC 次數才能回收完原有數量的垃圾. 參數配置:
//GC停頓時間,垃圾收集器會嘗試用各種手段達到這個時間 -XX:MaxGCPauseMillis
8.4 調整內存區域大小比率
現象:某一個區域的GC頻繁,其他都正常。 原因:如果對應區域空間不足,導致需要頻繁GC來釋放空間,在JVM堆內存無法增加的情況下,可以調整對應區域的大小比率。 注意:也許并非空間不足,而是因為內存泄造成內存無法回收,從而導致 GC 頻繁。 參數配置:
//survivor區和Eden區大小比率 指令:-XX:SurvivorRatio=6 //S區和Eden區占新生代比率為1:6,兩個S區2:6 //新生代和老年代的占比 -XX:NewRatio=4 //表示新生代:老年代 = 1:4 即老年代占整個堆的4/5;默認值=2
8.5 調整對象升老年代的年齡
現象:老年代頻繁 GC,每次回收的對象很多。 原因:如果升代年齡小,新生代的對象很快就進入老年代了,導致老年代對象變多,而這些對象其實在隨后的很短時間內就可以回收,這時候可以調整對象的升級代年齡,讓對象不那么容易進入老年代解決老年代空間不足頻繁 GC 問題。 注意:增加了年齡之后,這些對象在新生代的時間會變長可能導致新生代的 GC 頻率增加,并且頻繁復制這些對象新生的 GC 時間也可能變長。 配置參數:
//進入老年代最小的GC年齡,年輕代對象轉換為老年代對象最小年齡值,默認值7 -XX:InitialTenuringThreshol=7
8.6 調整大對象的標準
現象:老年代頻繁 GC,每次回收的對象很多,而且單個對象的體積都比較大。 原因:如果大量的大對象直接分配到老年代,導致老年代容易被填滿而造成頻繁 GC,可設置對象直接進入老年代的標準。 注意:這些大對象進入新生代后可能會使新生代的 GC 頻率和時間增加。 配置參數:
//新生代可容納的最大對象,大于則直接會分配到老年代,0代表沒有限制。 -XX:PretenureSizeThreshold=1000000
8.7 調整GC的觸發時機
現象:CMS,G1 經常 Full GC,程序卡頓嚴重。 原因:G1 和 CMS 部分 GC 階段是并發進行的,業務線程和垃圾收集線程一起工作,也就說明垃圾收集的過程中業務線程會生成新的對象,所以在 GC 的時候需要預留一部分內存空間來容納新產生的對象,如果這個時候內存空間不足以容納新產生的對象,那么JVM就會停止并發收集暫停所有業務線程(STW)來保證垃圾收集的正常運行。這個時候可以調整GC觸發的時機(比如在老年代占用 60% 就觸發 GC),這樣就可以預留足夠的空間來讓業務線程創建的對象有足夠的空間分配。 注意:提早觸發 GC 會增加老年代 GC 的頻率。 配置參數:
//使用多少比例的老年代后開始CMS收集,默認是68%,如果頻繁發生SerialOld卡頓,應該調小 -XX:CMSInitiatingOccupancyFraction //G1混合垃圾回收周期中要包括的舊區域設置占用率閾值。默認占用率為 65% -XX:G1MixedGCLiveThresholdPercent=65
8.8 調整 JVM本地內存大小
現象:GC 的次數、時間和回收的對象都正常,堆內存空間充足,但是報 OOM 原因:JVM 除了堆內存之外還有一塊堆外內存,這片內存也叫本地內存,可是這塊內存區域不足了并不會主動觸發 GC,只有在堆內存區域觸發的時候順帶會把本地內存回收了,而一旦本地內存分配不足就會直接報 OOM 異常。 注意:本地內存異常的時候除了上面的現象之外,異常信息可能是 OutOfMemoryError:Direct buffer memory。解決方式除了調整本地內存大小之外,也可以在出現此異常時進行捕獲,手動觸發 GC(System.gc())。 配置參數:
XX:MaxDirectMemorySize
9. JVM 調試實戰
為什么要調整JVM
JVM調優背景
生產環境中的問題 生產環境發生了內存溢出該如何處理? 生產環境應該給服務器分配多少內存合適? 如何對垃圾回收器的性能進行調優? 生產環境 CPU 負載飆高該如何處理? 生產環境應該給應用分配多少線程合適? 不加 log,如何確定請求是否執行了某一行代碼? 不加 log,如何實時查看某個方法的入參與返回值?
為什么要調優
防止出現 OOM解決 OOM減少 Full GC 出現的頻率
不同階段的考慮
上線前項目運行階段線上出現 OOM
JVM調優方案
監控的依據
運行日志異常堆棧GC 日志線程快照堆轉儲快照
調優的大方向
合理地編寫代碼充分并合理的使用硬件資源合理地進行 JVM 調優
JVM性能優化的步驟
第 1 步:性能監控
GC 頻繁 cpu load 過高 OOM 內存泄露 死鎖 程序響應時間較長
第 2 步:性能分析
打印 GC 日志,通過 GCviewer 或者 Universal JVM GC analyzer - Java Garbage collection log analysis made easy 來分析異常信息 靈活運用命令行工具、jstack、jmap、jinfo 等 dump 出堆文件,使用內存分析工具分析文件 使用阿里 Arthas、jconsole、JVisualVM 來實時查看 JVM 狀態 jstack 查看堆棧信息
第 3 步:性能調優
適當增加內存,根據業務背景選擇垃圾回收器優化代碼,控制內存使用增加機器,分散節點壓力合理設置線程池線程數量使用中間件提高程序效率,比如緩存、消息隊列等其他……
性能評價/測試指標
**1 停頓時間(或響應時間):**提交請求和返回該請求的響應之間使用的時間,一般比較關注平均響應時間。常用操作的響應時間列表:
2 垃圾回收環節:
暫停時間:執行垃圾收集時,程序的工作線程被暫停的時間。-XX:MaxGCPauseMillis 表示每次GC最大的停頓毫秒
3 吞吐量
對單位時間內完成的工作量(請求)的量度在 GC 中:運行用戶代碼的事件占總運行時間的比例(總運行時間:程序的運行時間+內存回收的時間)吞吐量為 1-1/(1+n),其中-XX::GCTimeRatio=n
4 并發數
同一時刻,對服務器有實際交互的請求數
5 內存占用
Java 堆區所占的內存大小
6 相互間的關系
以高速公路通行狀況為例
吞吐量:每天通過高速公路收費站的車輛的數據并發數:高速公路上正在行駛的車輛的數目響應時間:車速
9.1 網站流量瀏覽量暴增后,網站反應頁面響很慢
1、問題推測:在測試環境測速度比較快,但是一到生產就變慢,所以推測可能是因為垃圾收集導致的業務線程停頓。 2、定位:為了確認推測的正確性,在線上通過 jstat -gc 指令 看到 JVM 進行 GC 次數頻率非常高,GC 所占用的時間非常長,所以基本推斷就是因為 GC 頻率非常高,所以導致業務線程經常停頓,從而造成網頁反應很慢。 3、解決方案:因為網頁訪問量很高,所以對象創建速度非???,導致堆內存容易填滿從而頻繁 GC,所以這里問題在于新生代內存太小,所以這里可以增加 JVM 內存就行了,所以初步從原來的 2G 內存增加到 16G 內存。 4、第二個問題:增加內存后的確平常的請求比較快了,但是又出現了另外一個問題,就是不定期的會間斷性的卡頓,而且單次卡頓的時間要比之前要長很多。 5、問題推測:之前的優化加大了內存,所以推測可能是因為內存加大了,從而導致單次 GC 的時間變長從而導致間接性的卡頓。 6、定位:還是通過 jstat -gc 指令 查看到 的確 FGC 次數并不是很高,但是花費在 FGC 上的時間是非常高的,根據 GC 日志 查看到單次 FGC 的時間有達到幾十秒的。 7、解決方案:因為 JVM 默認使用的是 PS+PO 的組合,PS+PO 垃圾標記和收集階段都是 STW,所以內存加大了之后,需要進行垃圾回收的時間就變長了,所以這里要想避免單次 GC 時間過長,所以需要更換并發類的收集器,因為當前的 JDK 版本為 1.7,所以最后選擇 CMS 垃圾收集器,根據之前垃圾收集情況設置了一個預期的停頓的時間,上線后網站再也沒有了卡頓問題。
9.2 后臺導出數據引發的 OOM
問題描述:公司的后臺系統,偶發性的引發 OOM 異常,堆內存溢出。 1、因為是偶發性的,所以第一次簡單的認為就是堆內存不足導致,所以單方面的加大了堆內存從 4G 調整到 8G。 2、但是問題依然沒有解決,只能從堆內存信息下手,通過開啟了 -XX:+HeapDumpOnOutOfMemoryError 參數 獲得堆內存的 dump 文件。 3、VisualVM 對堆 dump 文件進行分析,通過 VisualVM 查看到占用內存最大的對象是 String 對象,本來想跟蹤著 String 對象找到其引用的地方,但 dump 文件太大,跟蹤進去的時候總是卡死,而 String 對象占用比較多也比較正常,最開始也沒有認定就是這里的問題,于是就從線程信息里面找突破點。 4、通過線程進行分析,先找到了幾個正在運行的業務線程,然后逐一跟進業務線程看了下代碼,發現有個引起我注意的方法,導出訂單信息。 5、因為訂單信息導出這個方法可能會有幾萬的數據量,首先要從數據庫里面查詢出來訂單信息,然后把訂單信息生成 excel,這個過程會產生大量的 String 對象。 6、為了驗證自己的猜想,于是準備登錄后臺去測試下,結果在測試的過程中發現到處訂單的按鈕前端居然沒有做點擊后按鈕置灰交互事件,結果按鈕可以一直點,因為導出訂單數據本來就非常慢,使用的人員可能發現點擊后很久后頁面都沒反應,結果就一直點,結果就大量的請求進入到后臺,堆內存產生了大量的訂單對象和 EXCEL 對象,而且方法執行非常慢,導致這一段時間內這些對象都無法被回收,所以最終導致內存溢出。 7、知道了問題就容易解決了,最終沒有調整任何 JVM 參數,只是在前端的導出訂單按鈕上加上了置灰狀態,等后端響應之后按鈕才可以進行點擊,然后減少了查詢訂單信息的非必要字段來減少生成對象的體積,然后問題就解決了。
9.3 Window JVM調優
查詢JDK所用虛擬機
java version "1.8.0_91"Java(TM) SE Runtime Environment (build 1.8.0_91-b14)Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)//支持 Java 8, 使用的是 Oracle 的64位HotSpot虛擬機。//HotSpot VM 是 OracleJDK / SunJDK 以及 OpenJDK 里的 JVM 實現。使用最廣泛,JDK默認安裝的。
Java問題診斷和排查工具(查看JVM參數、內存使用情況及分析等)
常用查詢命令
JPS (打印Java進程信息)
使用場景 : 查看當前機器的所有Java進程信息(可追蹤到應用進程ID 、啟動類名、文件路徑。)。jps 顯示當前所有java進程pid的命令jps -v 輸出傳遞給JVM的參數
jstack(JVM線程信息監控)
使用場景: 查看JVM線程信息 和生成線程快照。jstack pid 主要用于生成指定進程當前時刻的線程快照,線程快照是當前java虛擬機每一條線程正在執行的方法堆棧的集合。分析線程棧
Jmap(JVM內存占用信息和快照)
使用場景: 監控堆內存使用情況和對象占用情況, 生成堆內存快照文件,查看堆內存區域配置信息。**jmap **打印指定java進程的共享對象內存映射或堆內存細節。堆Dump是反映堆使用情況的內存鏡像,其中主要包括系統信息、虛擬機屬性、完整的線程Dump、所有類和對象的狀態等。
**jmap pid **共享對象的起始地址、映射大小、共享對象路徑的全程。 jmap -heap pid:查看堆使用情況jmap -histo pid:查看堆中對象數量和大小
Jstat (JVM內存信息統計)
使用場景 :用于查看各個功能和區域的統計信息(如:類加載、編譯相關信息統計,各個內存區域GC概況和統計)jstat-gc pid: 統計垃圾回收堆的行為
Jinfo(JVM參數查看和修改)
使用場景: 查看和調整JVM啟動和運行參數。
Jinfo pid 查看JVM整個系統參數信息jinfo -flag [參數名] pid 查看某個具體參數jinfo -flag啟動某個配置
java查詢JVM配置參數
查詢JVM配置參數java -XX:+PrintCommandLineFlags
C:\Program Files\Java\jdk1.8.0_91\bin>java -XX:+PrintCommandLineFlags-XX:InitialHeapSize=199690240 //初始堆大小bytes 這里23M-XX:MaxHeapSize=3195043840 //最大堆大小bytes 這里380M-XX:+PrintCommandLineFlags //PrintCommandLineFlags 是打印那些被新值覆蓋的項-XX:+UseCompressedClassPointers //UseCompressedClassPointers:類指針壓縮-XX:+UseCompressedOops //UseCompressedOops:普通對象指針壓縮-XX:-UseLargePagesIndividualAllocation //關閉減少處理器 TLB 緩存壓力的技術-XX:+UseParallelGC //設置并行收集器 “Parallel Scavenge” + "Parallel Old"組合
查詢JVM配置參數java -XX:+PrintFlagsFinal -version |FINDSTR /i “:”
C:\Program Files\Java\jdk1.8.0_91\bin>java -XX:+PrintFlagsFinal -version |FINDSTR /i ":" intx CICompilerCount := 3 {product} uintx InitialHeapSize := 201326592 //初始堆大小bytes {product} uintx MaxHeapSize := 3196059648 //最大堆大小bytes {product} uintx MaxNewSize := 1065353216 //新生代分配內存最大上限,小于-Xmx的值; {product} uintx MinHeapDeltaBytes := 524288 //要擴容或者縮容最小擴/縮多少 {product} uintx NewSize := 67108864 //新生代初始內存的大小,應該小于-Xms的值; {product} uintx OldSize := 134217728 //老年代的默認大小 {product} bool PrintFlagsFinal := true //打印所有的默認參數設置 {product} bool UseCompressedClassPointers := true {lp64_product} bool UseCompressedOops := true {lp64_product} bool UseLargePagesIndividualAllocation := false {pd product} bool UseParallelGC := true {product}java version "1.8.0_91"Java(TM) SE Runtime Environment (build 1.8.0_91-b14)Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
配置Windows JVM參數
1、系統環境中配置(推薦)
虛擬機內存的大小除了在web容器中設置,我們還可以通過系統環境變量來設置,下面看看設置步驟: 打開windows系統環境變量,在系統變量中,新建變量JAVA_OPTS,值設置為:
8G物理內存JVM虛擬機配置idea優化命令-XX:+UseG1GC -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=95 -Xms5120m -Xmx5120m -Xmn1024m -Xss128k -XX:MaxTenuringThreshold=0jdk8 使用G1垃圾回收器-XX:-UseParallelGC -Xms3550m -Xmx3550m -Xmn1024m -Xss128k -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=95 -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MatespaceSize=6
優化前啟動優化前jmeter測試
優化后啟動優化后jmeter測試
jvm中常用的參數含義:
每個對象都有一個計數器,每次YGC 都會加1,配置計數器的值到達某個闡值的時候, 對象從 新生代晉升至老年。 -XX:MaxTenuringThreshold
為功能點比較多,在運行過程中,要不斷動態加載很多的類,經常出現致命錯誤。為了解決該問題, 需要設定運行參數 -XX: MaxPermSize= 1280m ,
以給NM 設置運行參數讓JVM 遇到OOM 異常時能輸出堆內信息。 -XX:+HeapDumpOnOutOfMemoryError
1: -Xmx指定 jvm 的最大內存大小 , 如 :-Xmx=2048M(根據設備物理內存以及實際情況設定,建議為物理內存的80%) 2: -Xms指定 jvm 的初始內存大小 , 如 :-Xms=2048M, 高并發應用, 建議和-Xmx一樣, 防止因為內存收縮/突然增大帶來的性能影響. 3: -Xmn指定 jvm 中 New Generation (堆空間的新生代空間)的大小 , 如 :-Xmn=256m。 這個參數很影響性能, 如果你的程序需要比較多的臨時內存, 建議設置到512M, 如果用的少, 盡量降低這個數值, 一般來說128/256足以使用了。 4: -XX:PermSize (java7,java8移除)指定 jvm 中 Perm Generation (永久存儲區)的最小值 , 如 :-XX:PermSize=32m。 這個參數需要看你的實際情況??梢酝ㄟ^jmap 命令看看到底需要多少。 5: -XX:MaxPermSize(java7,java8移除)指定 Perm Generation 的最大值 , 如 :-XX:MaxPermSize=64m 6: -Xss指定線程桟大小 , 如 :-Xss=128k, 一般來說,webx框架下的應用需要256K。 如果程序中有大規模的遞歸行為,請考慮設置到512K/1M。 這個需要全面的測試才能知道。 不過,256K已經很大了。 這個參數對性能的影響比較大的。 7:-XX:MatespaceSize(java8)和-XX:MatespaceSize(java8)JVM加載類的時候,需要記錄類的元數據,這些數據會保存在一個單獨的內存區域內,在Java 7里,這個空間被稱為永久代(Permgen),在Java 8里,使用元空間(Metaspace)代替了永久代。由于調整元空間的大小需要Full GC,這是非常昂貴的操作,如果應用在啟動的時候發生大量Full GC,通常都是由于永久代或元空間發生了大小調整,基于這種情況一般建議在JVM參數中將MetaspaceSize和MaxMetaspaceSize設置成一樣的值,并設置得比初始值要大,對于8G物理內存的機器來說,一般我會將這兩個值都設置為512M。
2、使用命令配置
java命令配置
8G物理內存JVM虛擬機配置java -XX:+UseG1GC-Xms3550m -Xmx3550m -Xmn1024m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MatespaceSize=512m -XX:MaxMetaspaceSize=512m -XX:MaxTenuringThreshold=0
使用 -Xms 設置堆的初始空間大小 java -Xms20m -Xmx30m GCDemo
JVM 提供了參數 -Xmn 來設置年輕代內存的大小 java -Xms20m -Xmn10M GCDemo
使用 -XX:SurvivorRatio 這個參數,該參數設置 eden / from 空間的比例關系 -XX:SurvivorRatio = eden/from = eden/to java -Xms20m -Xmn10M -XX:SurvivorRatio=2 -XX:+PrintGCDetails GCDemo
永久代(JDK1.7)所加載的類信息都放在永久代中。用 -XX:PermSize 設置永久代初始大小,用 -XX:MaxPermSize 設置永久代最大大小。 java -XX:PermSize=10m -XX:MaxPermSize=50m -XX:+PrintGCDetails GCDemo
元空間(JDK1.8)在 JDK1.8 之時,永久代被移除,取而代之的是元空間 java -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=50m -XX:+PrintGCDetails GCDemo
??臻g是每個線程各自有的一塊區域,如果??臻g太小,也會導致 StackOverFlow 異常。而要設置??臻g大小,只需要使用 -Xss 參數就可以。 java -Xss2m GCDemo
在 JVM 中還有一塊內存,它獨立于 JVM 的堆內存,它就是:直接內存。 java -XX:MaxDirectMemorySize=50m GCDemo
實時修改JVM參數:jinfo -flag name = value PID 如果要對參數進行實時調整:則需要看到參數后面有manageable的才能被實時調整
9.4 Linux JVM調優
基本同windows,只是命令上大同小異。 使用命令配置
8G物理內存JVM虛擬機配置java -XX:+UseG1GC-Xms3550m -Xmx3550m -Xmn1024m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MatespaceSize=512m -XX:MaxMetaspaceSize=512m -XX:MaxTenuringThreshold=0
參考鏈接
jmeter
https://cloud.tencent.com/developer/article/1633626 https://blog.csdn.net/wust_lh/article/details/86095924 https://blog.csdn.net/qq_37453279/article/details/107990659 https://zhuanlan.zhihu.com/p/142897766
獲取jvm日志
https://blog.csdn.net/zlzlei/article/details/46471627 https://blog.csdn.net/S1124654/article/details/125467265 https://www.jianshu.com/p/0167a0fc8063 [https://zhuanlan.zhihu.com/p/355765061[https://blog.csdn.net/qq_35925558/article/details/116464460
jvm監控調優關注參數指標
[https://blog.csdn.net/weixin_41605937/article/details/121704836https://blog.csdn.net/weixin_43935927/article/details/109233111 [https://zhuanlan.zhihu.com/p/269597178[https://zhuanlan.zhihu.com/p/267381560
jvm調優
https://blog.csdn.net/augsm/article/details/109272205 https://tianweichang.blog.csdn.net/article/details/109712806 https://heapdump.cn/ https://mp.weixin.qq.com/s?__biz=MzkwNjMwMTgzMQ==&mid=2247495919&idx=1&sn=71010d91e376270afc31bbe61c8326aa&chksm=c0e82807f79fa111d7c339832f48c9542d5fc1540c1a619c1a3281040fc1631616e016d0dc36&mpshare=1&scene=23&srcid=0630pKVRvfxq3GMy1Oa2Wxda&sharer_sharetime=1656582521218&sharer_shareid=4b447a3cb6ab5d3443a5fc9771951705#rd https://www.cnblogs.com/z-sm/p/6745375.html https://www.cnblogs.com/zhi-leaf/p/10629033.html https://blog.csdn.net/weixin_43474695/article/details/108248756
https://blog.csdn.net/weixin_28864057/article/details/119661743 https://blog.csdn.net/qq_40902067/article/details/106003880
idea中設置JVM參數
https://zhuanlan.zhihu.com/p/117627812
Java自定義類加載器
https://blog.csdn.net/weixin_42759726/article/details/114030153
查詢JVM配置參數分析參考
https://blog.csdn.net/m0_45406092/article/details/110766297 https://www.cnblogs.com/milton/p/6134251.html https://blog.csdn.net/qq13933506749/article/details/120187991 https://www.cnblogs.com/yidaixiaohui/p/10216180.html
JVM關鍵參數
https://www.cnblogs.com/bapiera/p/13592525.html https://www.cnblogs.com/GtShare/p/9767768.html https://jishuin.proginn.com/p/763bfbd66a1c https://blog.csdn.net/a469517790/article/details/104916916 https://blog.csdn.net/a469517790/article/details/104916916 https://blog.csdn.net/m0_45406092/article/details/110766297
JVM參數之堆??臻g配置
https://blog.csdn.net/qq_40902067/article/details/106003880 https://blog.csdn.net/weixin_28864057/article/details/119661743
JDK8使用G1無效
https://blog.csdn.net/weixin_42629445/article/details/120717860 https://bbs.huaweicloud.com/blogs/247828 https://www.jianshu.com/p/7dd309cc3442 https://www.cnblogs.com/frankyou/p/15048531.html https://blog.csdn.net/Megustas_JJC/article/details/105470675 https://zhuanlan.zhihu.com/p/458098236
java程序輸出jvm參數
https://blog.csdn.net/sjl110/article/details/41516745
JDK1.8默認垃圾回收器
https://blog.csdn.net/qq_27500493/article/details/108063108
JVM垃圾收集器【Serial、ParNew、PS、CMS、Serial Old、PO、G1】總結
https://blog.csdn.net/qq_43661709/article/details/122793803
windows配置jVM
https://blog.csdn.net/qq_38776582/article/details/109738067 https://blog.csdn.net/mhqyr422/article/details/79691042
標簽:
相關推薦:
精彩放送:
- []在哪里看股指期貨的行情?股指期貨行情信息
- []當前動態:基金定投可以隨時取出來嗎
- []Java進階1-JVM虛擬機 JVM在字節碼上的使用方法
- []5.0以下的主流圖片加載框架有哪些?安卓加載圖片四大框架
- []環球微頭條丨如何使用視頻剪輯軟件將qsv格式視頻轉換為MP4格式?方法步驟
- []環球今日報丨中國“北斗”衛星導航系統——定位模塊需求介紹
- []如何利用大數據實現精準營銷?會員管理中用戶數據的流轉及應用邏輯
- []世界快看:操作系統中死鎖的算法——銀行家算法
- []當前資訊!DirectSound能幫我們做什么?DirectSound開發指南
- []“流氓”劉邦戰勝英雄項羽的因素有哪些?詳情介紹
- []當前熱門:【干貨】Python與STAT時間日期轉換問題
- []]天天精選!iOS13越獄教程:如何安裝AppSync和afc2補???
- []全球觀速訊丨st股票什么股
- []股票開戶需要多少錢
- []海昌海洋公園2022年營收同比下降近七成,將持續發展頂流IP
- []鏈家將27座城市轉為加盟模式?貝殼:消息不實,僅為小范圍合伙人模式
- []當前速訊:美達股份:公司生產的部分產品可在軍民融合領域進行應用,具體請以公司公告和定期報告為準
- []每日看點!國??萍迹褐袊某鞘熊壍澜煌ㄈ詣舆\行(無人駕駛)信號系統處于國際先進水平
- []【全球報資訊】悅榕集團2022財年總計63家酒店收官 計劃2025年擴張至113家
- []全球看熱訊:我愛我家副總裁何洋辭任
- []我愛我家:五八有限公司擬減持不超過2.74%股份 持股比例將低于5%
- []中國恒大披露重組進展
- []電科院:公司具體經營情況詳見以往定期報告
- []焦點訊息:航班老是臨時取消?民航局要出手了
- []環球新資訊:國泰君安醫藥一季報業績前瞻:業績復蘇環比趨勢明確
- []【速看料】中信建投:TOPCon電池、組件超額利潤有望擴大
- []眼看AI主題基金起高樓 “消費選手”仍在默默堅守
- []天天亮點!AI+元宇宙!Meta離夢想更進一步?
- []蘇州常熟2宗宅地將于5月5日出讓 起價合計5.4億元
- []昭衍新藥:公司會緊跟行業技術的發展變化,學習和借鑒相關技術在安評業務中的運用
- []環球百事通!中南建設前3月合同銷售額120.4億元 同比減少26.2%
- []消息!南昌中溢置業將轉讓杭州通原地產40%股權 底價8031.3萬元
- []亞通精工:公司未有應披露而未披露事項,股價漲跌受多種因素影響,股價波動是正常的市場交易行為
- []西安國際港務區掛牌2宗宅地面積共117畝 起始總價為7.894億元
- []財面兒丨越秀地產1-3月累計合同銷售額約人民幣438.33億元 同比上升約217.3%
- []當前視點!海容冷鏈:公司產品不應用于殯葬行業,公司產品應用于快速消費品行業的渠道建設
- []每日時訊!將優化調整高校兩成左右學科專業布點
- []【全球報資訊】合肥放開部分區域限購! 多孩家庭可買第3套住房
- []世界今日訊!鏈家欲在北京、上海以外城市轉為加盟模式?貝殼回應:無此計劃
- []每經熱評|當前并非出臺房產稅政策的好時機
- []天天訊息:一個月的寶寶很容易被驚嚇怎么辦_一個月的寶寶發育指標
- []【熱聞】怎樣取公積金
- []今日熱門!怎么取公積金
- []天天快看:交強險怎么用
- []貝殼:鏈家將27座城市轉為加盟模式消息不實 僅為小范圍合伙人模式
- []當前消息!滕哈赫:現在才是賽季真正的開始,輸給紐卡后我們要有積極回應
- []道達爾能源與伊拉克政府就100億美元天然氣開發項目達成一致
- []世界快資訊丨林斌辭任奧園美谷財務總監職務?江永標繼任
- []中南建設:中南城投減持212.03萬股 占所持股比例0.11%
- []天天百事通!中南建設前三月累計合同銷售金額120.4億元 同比降26.2%
- []胡泊、李強分別辭任南國置業聯席總經理、副總經理
- []萬達投資新增質押1930萬股萬達電影 累計質押6665萬股
- []環球今頭條!劉鑫獲任榮盛發展副總裁
- []全球熱文:廈門象嶼與河南能源集團簽訂戰略合作協議
- []環球最新:4月05日20時青海海東今天新增確診名單 4月05日20時青海海東疫情防控政策最新通知
- []當前視點!一半鄉土質樸,一半文藝先鋒,沙漠河流共生的小城,最美季節到了
- []全球熱門:戶用儲能系統有什么用,有哪些特點和應用?
- []全球看熱訊:長久物流設立儲能全資子公司!
- []天天亮點!不低于1GW!泰達股份聯手千泉實業投建光伏項目
- []30萬噸光伏玻璃硅砂提純項目環評
- []天天視點!超10GW!TCL中環單月出貨新突破
- []一彬科技:公司生產經營一切正常。公司對未來汽車產業的發展充滿信心
- []國際油價小跌,受制于美國制造業降溫,本周重頭戲待上演
- []焦點要聞:深圳到九江火車時刻表查詢_南昌到九江火車時刻表
- []醫道彤行,厚積薄發|2021道彤投資年度合伙人大會特寫
- []海淘的childlife大瓶鈣含防腐劑?專家建議嬰幼兒產品選購要謹慎
- []好好香鍋公司怎么樣
- []觀察:鴻路鋼構:鋼結構是綠色節能產品,是國家提倡并大力推廣的裝配式建筑的重要組成部分
- []基金經理猛追AI 但斌卻突然唱空:一旦被套 不知猴年馬月解套
- []關注:難道是真的?青海發現形狀怪異的遺骸,揭開大禹治水背后的真相!
- []世界微頭條丨維宏股份:整個Phoenix平臺包含了軟件和硬件兩個部分
- []簡訊:拜登:人工智能是否危險還有待觀察 但科技公司需為安全負責
- []世界聚焦:2023年Q1季度精選文章合集 | 商旅會獎賽道
- []觀速訊丨申請破產!暴跌90%
- []【全球新要聞】2023年Q1季度精選文章合集 | 在線旅游/分銷賽道
- []每日關注!四川宜賓:住房公積金最高貸款額度可達90萬元
- []全球快訊:伊戈爾:公司會根據客戶需求和業務開拓的情況提前布局或者調整相應的產能
- []越秀地產:一季度累計銷售約438億元
- []環球今日訊!合肥調整購房政策:部分區域放開限購
- []全球微資訊!全國春風地圖出爐 看看你那兒的四月天
- []環球關注:黃金大漲近2% 逼近歷史最高紀錄!金價為何持續大漲?專家解讀
- []當前快報:是否想念籃球?維金斯:我非常想念隊友們 期待與他們并肩作戰
- []外匯交易提醒:降息預期升溫,美元跌創近兩個月新低,新西蘭聯儲決議來襲,紐元續漲有望
- []周鴻祎突然離婚,要AI不要愛?董秘回應來了
- []accountnumber怎么讀_Accountnumber
- []4月5日財經早餐:美數據疲軟強化美聯儲放緩加息押注,金價站上2000美元/盎司大關創三十二個月新高
- []【世界聚看點】高達65%成本節約 施耐德電氣適配改造服務助企業把握“循環”機遇
- []銀行信貸投放不足原因_銀行信貸的作用
- []恒達集團控股2022年收入增加約3.4% 純利減74.3%至7780萬
- []環球速讀:車險傭金
- []看熱訊:三大保險
- []熱訊:壽險功用
- []當前資訊!聚焦中概 | 小鵬汽車跌幅擴大至7% 造車新勢力普跌
- []雙十原則
- []當前快看:烏龜冬眠是為了放水還是放沙?
- []天天快消息!周鴻祎與胡歡離婚 后者分得三六零4.46億股、對應市值近90億元
- []環球觀熱點:周度經濟觀察:斜率放緩的經濟復蘇
- []世界觀焦點:申通快遞:公司與阿里云合作,通過引入云原生技術實現了技術全面升級
- []全球短訊!深交所、滬交所4月8日全面實行注冊制交易業務通關測試
- B站注冊資本增幅400%至5億 目前由陳睿全資持股
- 光源資本出任獨家財務顧問 沐曦集成電路10億元A輪融資宣告完成
- 巨輪智能2021年上半年營收11.24億元 期內研發費用投入增長19.05%
- 紅棗期貨尾盤拉升大漲近6% 目前紅棗市場總庫存約30萬噸
- 嘉銀金科發布2021年Q2財報 期內凈利潤達1.27億元同比增長208%
- 成都銀行2021上半年凈利33.89億元 期內實現營收同比增長17.27億元
- 汽車之家發布2021年第二季度業績 期內新能源汽車品牌收入增長238%
- 中信銀行上半年實現凈利潤290.31億元 期末不良貸款余額706.82億元
- 光伏概念掀起漲停潮交易價格創新高 全天成交額達1.29億元
- 上半年生物藥大增45% 關鍵財務指標好轉營收賬款持續下降
- 亞太藥業向下修正可轉債價格 律師:索賠宜趁早
- 假期安全注意事項內容圖片_假期安全注意事項內容
- 香山股份:目前尚無詳細的市場份額數據,更多詳情敬請留意公司官網及相關公告和定期報告
- 全球快看:秦安股份:4月3日公司高管劉宏慶減持公司股份合計1.16萬股
- 保利發展:房地產持續向好的基本面沒有變
- 世界快資訊:越秀地產前三月銷售438億?同比上升217%
- 當前聚焦:格力地產:珠海國資委同意公司收購免稅集團 并募資不超70億元
- 天天觀點:保利發展:公司負債率連續三年下降 繼續保持穩健財務政策
- 保利發展:靈活安排推貨節奏?把握市場修復窗口
- 今日要聞!國家加強鐵礦石價格形勢分析研判和期現貨市場監管
- 世界熱資訊!寶馨科技:目前公司懷遠一期2GW異質結電池及組件項目正在加速推進中,預計年內投產
- 天天觀點:中交城投鄭州古滎城更項目獲得首筆融資
- 嶺南股份:公有云是云計算的主要形態。公司已與騰訊建立云計算、數字虛擬人、大數據等方面的戰略合作
- 世界短訊!西安土拍市場“活”了?
- 世界快報:湖北襄陽高新區2.08億售出65畝宅地 競得者為本地房企
- 今日熱訊:協創數據:公司存儲設備主要與聯想集團合作
- 【全球播資訊】三代人七十余載接力守護156座抗美援朝烈士墓
- 全球觀天下!每日互動:AIGC和ChatGPT都是融合多種AI技術的成果
- 天天滾動:神州高鐵:截至2023年3月31日,公司股東人數為91207
- 【天天新要聞】昭衍新藥:股價走勢受多方面因素的影響,還請謹慎投資
- 世界滾動:財面兒丨建發國際:前3月權益銷售額353.4億元,同比增長63.5%
- 全球實時:土地注冊處:香港3月樓宇買賣合約8599份 按年升124.6%
- 【天天新要聞】昆明公租房開發公司最終發行6億 品種一利率6.5%、品種二未發行
- 全球觀點:拼多多升級組織架構 聯合創始人趙佳臻出任聯席CEO搭檔陳磊
- 上海3月新建商品住宅成交面積環比增長94% 均價下跌2.8%
- 天天最資訊丨迪馬股份為江蘇2家子公司提供融資擔保 涉資8.04億元
- 滾動:狂飆910%!德國大儲市場崛起,戶儲地位岌岌可危?
- 新消息丨最新進展!中科云網5GW TOPCON電池項目一期簽署建設施工合同
- 焦點信息:煤矸石綜合利用與礦山生態修復的戰略思考
- 環球觀熱點:年產500萬噸!全球規模最大光伏砂項目成功簽約
- 最大涉水750mm 北京越野BJ60新增車型上市售24.58萬-27.68萬元
- 【天天播資訊】晶硅組件有什么作用和特點,有哪些種類?
- 環球旅訊+WiT新加坡主題沙龍開場演講:你好,中國!
- 天天報道:新地University Hill料最快4月底開售
- 環球速遞!萬通發展:萬通控股解質押270萬股股份 現持公司股份3.34億股
- 全球微動態丨建發房地產:10億元公司債券票面利率為4.25%
- 世界頭條:中核鈦白:公司第三期員工持股計劃并未在2023年3月14日進行大宗交易
- 全球觀速訊丨祥生控股首季銷售額54.19億元 同比下滑38.73%
- 國際油價走強,但多頭須警惕OPEC+最新減產的潛在負效用
- 恒基達鑫:公司始終密切關注橫琴粵澳深度合作區相關的措施和政策情況,望能充分利用和享受到政策帶來的紅利
- 當前滾動:顧家家居:截至3月末累計回購股份106.28萬股 總代價4187.73萬元
- 海新能科: 截至2023年03月31日,公司股東總人數為45,272名
- 中紅醫療:我國丁腈手套產品與馬來西亞相比有一定的成本優勢
- 經緯輝開:副董事長擬減持公司不超0.39%股份
- 富力地產:2022年度凈虧損157.79億元 預計今年可售貨值超1250億元
- 全球熱點!小摩增持萬物云39.86萬股 總金額約1406.76萬港元
- 全球速訊:嶸泰股份:我公司上市公司同行有旭升集團、愛柯迪、文燦股份等
- 新大正:正積極推進收購云南滄恒投資80%股權 尚存在不確定性
- 環球要聞:航天發展:截至2023年3月31日,航天發展股東戶數為179,101戶
- 當前快播:NYMEX原油仍上看83.17美元
- 4月4日福晶科技漲停分析:3D感應,中科院系,光通信概念熱股
- 會德豐合作盤MIAMI QUAY I暫累售49伙 套現4.8億港元
- 環球速讀:“20綠城03”將于4月13日提前摘牌 發行金額為10億元
- 天天資訊:4月4日中儲股份漲停分析:央企改革,快遞物流,國企改革概念熱股
- 4月4日四川黃金漲停分析:黃金概念熱股
- 環球今日訊!信達證券發布金陵飯店研報 年報點評:全年業績穩中有增 布局中高端 注重品牌打造
- 焦點!學習心得怎么寫?學習心得范本?
- 怎樣追女生?追女孩子的方法有哪些?
- 環球觀熱點:仙劍奇俠傳3有哪些歌曲?仙劍奇俠傳3所有歌曲匯總?
- 合山市景點有哪些?合山市景點介紹?
- 每日短訊:降雨量50毫米是怎么計算的?降雨量50毫米的計算方法?
- 當前資訊!生物圈2號為什么會失???生物圈二號失敗的重要原因?
- 中青旅2022年營收64.17億元,旅行社業務虧損收窄
- 捷信金融怎樣貸款?捷信金融貸款條件有哪些?
- 環球熱議:lol英雄聯盟怎么觀戰?觀看別人的游戲戰斗方法?
- 每日看點!速干衣的特點有哪些?速干衣的主要功能是什么?
- 速訊:and1鞋子怎么樣?and1鞋子有哪些特點?
- 焦點簡訊:北京:加大老舊平房院落、老舊小區、危舊樓房和簡易樓等更新力度
- 世界熱文:常青股份:年報審計工作正在進行中,年報將于2023年4月26日披露
- 天天最新:山西大同:住房公積金貸款最高額度提至100萬元
- 環球今頭條!國際金價跌勢受限,美國數據再現疲軟,FED鷹派呼聲難響
- 美原油交易策略:需求預期接力,油價或延續漲勢
- 環球新消息丨蘇泊爾擬分紅24.40億元 控股股東SEB國際或分得20.12億元
- 千方科技:公司未參與您所提及的業務
- 當前快播:河南新鄉:住房公積金最高貸款額度升至65萬元
- 全球速讀:發改委:產業目錄引導橫琴加大對新興產業等的培育
- 焦點消息!年報橫評①| 這些物企表現最好!五大指標透視2022年指標之最
- 世界焦點!醫貝云服銷售總監陳小飛:醫貝云服伴隨著藥品和耗材供應鏈改革而誕生
- 孕婦補鈣用金丐,早吃早手藝
- 環球新資訊:甘化科工:截至2023年3月31日,公司股東人數為27,947戶
- 天天動態:上海新華聯國際獨棟商墅第三次流拍 起始價1.29億元
- 焦點精選!明陽智能:尊敬的公司公司對外信息披露均按照信息披露要求進行
- 環球時訊:德恩精工子公司擬與億盛房地產合作開發“濱江一號”項目 預計總投資約1.4億元
- 環球今日訊!二手房成交量“狂飆”,百城落地“帶押過戶”
- 環球焦點!國際金價短線下看1970美元
- 【天天熱聞】上海鋼聯:根據創業板上市公司相關規則,創業板上市公司無需披露季度業績預告
- 非凡舞蹈學院創辦人Jamila 王海青,打破自我,永不設限!善濟有約
- 股票進倉是什么意思
- 云南省餐飲行業協會交流座談會在文山舉行
- “AI”拼才會贏?16只基金單日飆漲超7% 公募基金開始密集大調倉
- 三圍怎么量
- 當前焦點!炒外匯為什么要拉人
- 用了“借錢三巨頭”之一的錢小樂,真實感受:靠譜!
- 手機炒股票用什么軟件最好
- 全球信息:收購瑞信后 瑞銀將取代摩根大通成為拉美最大財富管理公司
- 市場對黃金ETF和金幣的興趣激增,渣打稱這還只是開始!
- 天天熱點!現貨黃金交易策略:美元仍存下行風險,金價或震蕩上攻
- 對沖基金放棄看空押注,金銀正蓄勢待漲!
- 當前播報:長春城投10億元私募債券項目狀態更新為“已反饋”
- 全球看點:北京:土地出讓收入用于農業農村比例不低于7.5%