用這個工具查到了內(nèi)存浪費的地方

簡單的科普一下吧

windows下的使用方法
命令行輸入tasklist找到要檢測的java進程的pid
(linux下直接ps -ax找到進程的pid)

如果把jdk的bin配到path里邊的話
直接輸入
jmap -histo pid > E:\output.txt

就可以把得到的內(nèi)容到E:\output.txt了,

打開后會發(fā)現(xiàn)內(nèi)容格式是類似這樣的:


num   #instances    #bytes  class name
--------------------------------------
  1:    427398    14458448  [I
  2:    178798     6830216  [C
  3:     50278     6668512  <constMethodKlass>
  4:    179924     4318176  java.lang.String
  5:     50278     4026648  <methodKlass>
  6:     15244     3894200  [B
  7:     47809     1773776  [Ljava.lang.Object;
...
...
...
Total  1645187    81806088

他的輸出是按照總占用內(nèi)存排序的
num是排序

#instance是對象的實例個數(shù)

#bytes是總占用的字節(jié)數(shù)

class name對應(yīng)的就是Class文件里的class的標識
B代表byte
C代表char
D代表double
F代表float
I代表int
J代表long
Z代表boolean
前邊有[代表數(shù)組,[I 就相當于int[]

對象用[L+類名表示

具體可以參考JVM的規(guī)范

有幾個方法可以用

1、通過#instance和#bytes可以得到每個對象的占用內(nèi)存平均值

注意這個只是對象本身占用的內(nèi)存
比如你有個類
A{
        int i;
        B b;
        public A(){
                b = new B()
        }
}
則A a = new A();
a實例占用內(nèi)存的字節(jié)數(shù)為16字節(jié)(int 4字節(jié)+B引用 4字節(jié)+對象本身8字節(jié))
不包含內(nèi)部引用b的實例的內(nèi)存占用字節(jié)數(shù)

2、可以通過對#instance或者#bytes進行排序,觀察每個對象的數(shù)目
對程序中生成的實例過多或者內(nèi)存占用過多的對象進行優(yōu)化或者找到內(nèi)存泄漏的地方