什麼是垃圾?
沒有任何引用指向的對象就是垃圾
怎麼找到一個垃圾?
常用的技術一:引用計數
記錄目前的空間有多少個對象在引用,當數值變成一了,就垃圾回收
常用的技術二:根可達算法
哪些對象是根對象?
jvm stack
native
method
pool 等等
如何清除一個垃圾?
一共就三種算法
- Mark-Sweep 标記清除
- Copying 拷貝
- Mark-Compact 标記壓縮
Mark-Sweep

優點:簡單
缺點:碎片化,所謂的碎片化就是指的一個空間裡清除的區域東一個西一個,千瘡百孔,找不到一個連續的空間存儲
Copying
規定空間隻能使用一半,将資料存儲之後,然後将另外一半 複制過去
缺點:浪費空間
Mark-Compact
先把要回收的弄到一塊區域,集中回收
缺點:效率低
☆☆☆Garbage collectors 垃圾回收器☆☆
新生代 和 老年代?
每經過一個垃圾收集器處理,年齡加1,回收過好幾遍都回收不掉的稱為老年代
PS + PO
經常配合使用的是:
parnew 和 cms
serial 和 serial old
PS 和 PO
堆記憶體邏輯分區
新産生的對象都會存才Eden區域,但是采用的是複制算法,淘汰的對象很多,隻有少部分資料可以進入 survivor區域,survivor區域總有一個是空的。
預設新生代和老年代的占空間大小為1:2,老年代空間要大些,可以自己調節。大小調節不規範就會産生很多問題,比如後面的full gc
Serial
STW: stop-the-world :立刻停止事件
停止之後進行垃圾回收,停止時間從幾秒可以到3天
JVM第一個調優:重新開機
CMS:承前啟後
工作在老年代,mark sweep 碎片化
暫停時間很短
并發執行:垃圾回收線程和工作線程同時執行
沖突:
有些垃圾在某些情況下又不是垃圾了
記憶體比較少的時候,serial和serial old配合
記憶體越來越大,parallel scavenge 和 parallel old 配合
記憶體更大的時候,parnew 和CMS配合
cms有一個巨大的毛病:用通俗的話來說,可能會産生一個阿姨打掃整個100層樓的酒店情況,會非常的 耗時
jdk 1.8預設的回收機制:PS/PO
jdk 1.8以上預設回收機制:G1
什麼是調優
1、。。。。。
2、優化jvm的運作環境
3、解決jvm運作時出現的問題(OOM:記憶體洩漏)
了解記憶體洩漏:這空間被占用,無法進行回收
記憶體溢出:占滿了,回收不了,記憶體崩了
處理cpu記憶體異常的工具:arthas
問題:線上運作的程式,cpu突然飙高,你怎麼解決這個問題?
定位線程
我們知道,Java是單程序多線程的,那麼,我們接下來看看PID=xxxx的這個Java程序中的各個線程的CPU使用情況,同樣是用top指令:
定位代碼
通過top指令,我們目前已經定位到導緻CPU使用率較高的具體線程, 那麼我麼接下來就定位下到底是哪一行代碼存在問題。
首先,我們需要把4519這個線程轉成16進制:
查找出哪些對象回收不了?
可以查找出哪些對象的實占記憶體最多
項目頻繁的full gc 你該怎麼做?
觸發原因有很多種,但歸根到底都是因為記憶體空間不足了
Full GC頻繁發生,意味着你的記憶體配置設定機制存在問題,也許是記憶體洩露,有大量記憶體垃圾不斷在老年代産生;也許是你的大對象(緩存)過多;也有可能是你的參數設定不好,minor GC清理不掉記憶體,導緻每次minor GC都會觸發Full GC;還有可能是你的老年代大小參數設定錯誤,老年代過小等等原因
1、如果每次gc之後剩餘的空間不大,說明有一部分頑固對象一直沒法被回收,導緻可用記憶體變少。這種情況下很容易後續出現oom,比如說一次大對象的申請
2、如果每次gc之後剩餘的空間比較大,意味着大部分對象都被清理了,但是系統又在頻繁的fullgc,說明很快老年代又會湧入大量對象。這個時候就應該檢查下jvm的參數配置,很有可能是新生代設定的太小了,導緻很多應該在minor gc階段就清理出去的對象留到了老年代,這種可能性是最大的
新生代可以分為eden、survivor0、survivor1,正常的對象配置設定都是在eden完成的,如果eden空間不夠了,會觸發一次minor gc,存活的對象放在s0或s1中。随着每次minor gc,存活的對象會不斷的從s0遷到s1,再從s1遷到s0,這個過程經過幾次之後,如果對象還是存活的,就會晉升到老年代。
但如果新生代大小設定的太小,就會導緻非常頻繁的minor gc,s0->s1來回切換的速度加快,導緻本身應該在minor gc就清理出去的對象跑到了老年代。
舉個例子,正常情況下如果minor gc是1分鐘一次,-XX:MaxTenuringThreshold預設配置是15的話,正常的小對象最長可以在新生代待15分鐘左右,如果一個對象o的存活時間是5分鐘,那它就可以在minor gc的時候被清理出去;但如果新生代設定過小,minor gc的頻率降到10秒一次,那麼o隻能在新生代待150秒左右,然後就會晉升到老年代,這種對象一多,就會導緻頻繁的fullgc