java中jvm

一:介紹

  • 什麼是JVM
    定義:java virtual meachine -java運行時環境(java二進制字節碼的運行環境)。
  • 好處:
    一次編寫到處運行
    自動內存管理,垃圾回收
    數組下標越界檢查
    多態
    在這裏插入圖片描述
    java虛擬機:

java的內存結構包括:

  • 程序計數器
  • 虛擬機棧
  • 本地方法棧
  • 方法區

1.1 程序計數器

在這裏插入圖片描述

  • java代碼在執行的過程:首先被編譯成二進制字節碼(jvm指令),然後通過解釋器生成爲機器碼,最後纔會被CPU執行。
  • 而解釋器在執行每一條字節碼指令時,需要程序計數器來指定需要執行的指令。此時程序計數器中存儲的是jvm下一個執行的地址
  • 正是因爲能編輯爲機器碼,jvm纔有一次編輯,多平臺使用。因爲無論linux和windows系統,都會執行機器碼

特點:

  • 線程私有
  • 不會出現內存泄漏

1.2 棧

1.2.1棧的定義

定義:

  • 每個線程運行時所需要的內存,稱爲虛擬機棧
  • 每個棧由多個棧幀組成,對應着每次方法調用時所佔用的內存
  • 每個線程只能有一個活動棧幀(正在執行的方法),對應着當前正在執行的那個方法
  • 特點:先進後出

一個線程需要一個棧;一個棧幀對應一個方法的調用;
棧和棧幀的關係:線程執行方法的時候,會調用方法,會將棧棧放入棧內,當方法執行完後,會將棧幀釋放掉
在這裏插入圖片描述
問題解析:
1:垃圾回收是否涉及棧內存
不涉及,方法執行完後,對應的棧幀就會被出棧,被釋放掉,不涉及垃圾回收
2:棧內存分配越大越好嗎?
不是:物理內存大小是一定的,當棧內存大時,線程數就會少。
3:方法內的局部變量是否線程安全?

  • 如果方法內局部變量沒有逃離方法的作用訪問,是線程安全的
  • 如果是局部變量引用了對象,並逃離方法的作用方法,需要考慮線程安全

查看線程是否安全:看這個變量對多個線程是共享的,還是私有的

public class Demo{
   static void hello(){
       int x=0;
       for (int i=0;i<100;i++){
       x++;
       }
System.out.println(x);

}
}

此時線程安全
在這裏插入圖片描述
此時局部變量是線程不安全的

public class Demo{
   static void hello(){
       static int x=0;
       for (int i=0;i<100;i++){
       x++;
       }
System.out.println(x);

}
}

在這裏插入圖片描述
在這裏插入圖片描述

1.2.2 棧內存溢出

STACKOVERFLOWERROE
什麼情況會導致內存溢出

  • 棧幀多時,一直有棧幀進棧;當遞歸次數多時
  • 棧幀過大導致內存溢出,

1.2.3 線程運行診斷

  • 案例一:cpu佔用過多
    定位

    • 用top定位哪個線程對cpu佔用過高
    • ps -H pid,tid,%cpu | grep 進程id,(用ps命令進一步定位那個線程引起的cpu佔用過高)
    • jstack 進程id
      • 可以根據線程id,找到問題的線程,進一步定位到出現問題的代碼
  • 案例二:一段程序,運行好長時間,沒有等到返回的結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章