java Jvm原理以及常見的jvm監聽工具

        
        
        JVM虛擬機學習:
        
            jvm內存區域:
                        
                    堆:
                    
                    棧(線程):線程棧,爲每一個線程在棧裏面分配內存空間。每一個線程分配一個棧內存空間,同時一個線程中的一個方法又會在這個棧內存空間站細粒度的分配一個棧幀空間。
                              局部變量在使用完成之後會銷燬給其分配的內存空間。
                              
                              線程中用new出來的對象、或者其他對象,會在棧裏面存儲該對象在堆裏面的地址信息,也就是堆對象的指針
                        
                    本地方法棧: 
                    
                    方法區(元空間):
                    
                    程序計數器:每一個線程運行時都會在棧內存中分配一塊程序技計數器的內存,程序計數器用來記錄程序運行到哪個位置,或者說哪一行。
                    
                    爲什麼要設計程序計數器或者說程序計數器的作用是什麼?
                    
                    程序計數器的作用是記錄他所對應的線程的執行位置。在多線程的情況下,有可能該線程未執行完畢就被掛起(如wait:),在他重新分配到cpu的時候從程序計數器裏面讀取到
                    它之前執行到的位置,再繼續執行。
                    
                    字節碼存儲引擎會去修改程序計數器中的值。
                    
                    
                    
            native修飾的方法是本地方法,使用c++寫的。調用本地方法時調用的是dll文件。如果調用到了本地方法會在本地方法棧中分配一塊空間
            
            
            GCROOTS:線程棧的本地變量、靜態變量,本地方法棧的變量等。
            
            >> 相當於除以2取下整。   3 >> 2 = 1 
            << 相當於左移動一位。   轉換爲2進制再向左邊移動一位
            
            jdk自帶的jvm監控工具: jvisualvm 需要下載插件即可監視visual GC
            
            爲什麼要jvm調優?
                減少stw(stop the world)的時間。減少full GC的次數,甚至不讓其發生fullGC。
                
                將年輕代的大小設置大一點,保持讓其每次minor GC移動到survival區的數據量的大小不到survival區大小的一半,就能夠儘量的減少full GC的次數。
                
            
            如果survival區中的對象大小超過了survival區大小的一半,就會直接將其放入老年代。
            
            
            
            jmm:
            
                一個線程 + 線程的緩存區 + 主內存(可以理解問棧或者堆))
                
                多個線程中的同一個對象數據都是通過對主內存中的數據進行copy,放在線程的緩存區的。
                
                如果有一個線程對該數據進行了修改,會先修改線程緩存中的值然後在寫會主內存,其他線程讀取的數據還是原來的數據,此時就會造成數據不一致性。
                
                
            解決方案一: 總線加鎖。對經過總線的每一個數據加鎖。缺點:多線程讀寫的時候,只有一條線程能同時對這個數據進行操作。
            
            解決方案二:volatile關鍵字。
            
                        1.每個jmm會對總線上進行監聽,只要線程緩存中的數據有變化就會將jmm緩存區中的數據設置爲失效,重新去主內存中獲取。
                        2.遵循MESI緩存一致協議
                        3.每一個線程都是在store的時候將數據加鎖。
                        
            jmm內存數據的獲取: read -> load ->use ->(if change) -> store(volatile會對對象進行lock) -> write
            
                
                
            
            

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