本文目錄一覽:
- 1、Java基本數據類型?
- 2、java裡面 類創建對象的時候,那麼這個對象在內存的模型是怎麼樣的??
- 3、JAVA中實例化一個對象,成員方法中的參數會在哪分配內存(棧/堆)?
- 4、Java內存模型FAQ 什麼是內存模型
- 5、如何查看java虛擬機堆內存的參數值
- 6、一個Java對象到底佔多大內存
Java基本數據類型?
一、基本數據類型:
byte:Java中最小的數據類型,在內存中佔8位(bit),即1個位元組,取值範圍-128~127,默認值0
short:短整型,在內存中佔16位,即2個位元組,取值範圍-32768~32717,默認值0
int:整型,用於存儲整數,在內在中佔32位,即4個位元組,取值範圍-2147483648~2147483647,默認值0
long:長整型,在內存中佔64位,即8個位元組-2^63~2^63-1,默認值0L
float:浮點型,在內存中佔32位,即4個位元組,用於存儲帶小數點的數字(與double的區別在於float類型有效小數點只有6~7位),默認值0
double:雙精度浮點型,用於存儲帶有小數點的數字,在內存中佔64位,即8個位元組,默認值0
char:字元型,用於存儲單個字元,佔16位,即2個位元組,取值範圍0~65535,默認值為空
boolean:布爾類型,佔1個位元組,用於判斷真或假(僅有兩個值,即true、false),默認值false
二、Java數據類型基本概念:
數據類型在計算機語言裡面,是對內存位置的一個抽象表達方式,可以理解為針對內存的一種抽象的表達方式。接觸每種語言的時候,都會存在數據類型的認識,有複雜的、簡單的,各種數據類型都需要在學習初期去了解,Java是強類型語言,所以Java對於數據類型的規範會相對嚴格。數據類型是語言的抽象原子概念,可以說是語言中最基本的單元定義,在Java裡面,本質上講將數據類型分為兩種:基本類型和引用數據類型。
基本類型:簡單數據類型是不能簡化的、內置的數據類型、由編程語言本身定義,它表示了真實的數字、字元和整數。
引用數據類型:Java語言本身不支持C++中的結構(struct)或聯合(union)數據類型,它的複合數據類型一般都是通過類或介面進行構造,類提供了捆綁數據和方法的方式,同時可以針對程序外部進行信息隱藏。
三、Java中的數據類型與內存的關係
在Java中,每個存放數據的變數都是有類型的,如:
charch;floatx;inta,b,c;
ch是字元型的,就會分配到2個位元組內存。不同類型的變數在內存中分配的位元組數不同,同時存儲方式也是不同的。
所以給變數賦值前需要先確定變數的類型,確定了變數的類型,即確定了數據需分配內存空間的大小,數據在內存的存儲方式。
四、Java數據類型在內存中的存儲:
1)基本數據類型的存儲原理:所有的簡單數據類型不存在「引用」的概念,基本數據類型都是直接存儲在內存中的內存棧上的,數據本身的值就是存儲在棧空間裡面,而Java語言裡面八種數據類型是這種存儲模型;
2)引用類型的存儲原理:引用類型繼承於Object類(也是引用類型)都是按照Java裡面存儲對象的內存模型來進行數據存儲的,使用Java內存堆和內存棧來進行這種類型的數據存儲,簡單地講,昆明北大青鳥認為「引用」是存儲在有序的內存棧上的,而對象本身的值存儲在內存堆上的。
java裡面 類創建對象的時候,那麼這個對象在內存的模型是怎麼樣的??
以下是內存分析圖。構造函數中,new Frame()只作為參數,傳遞給Container c;不存在包含關係,一個類的屬性引用了另一個類,而已。
JAVA中實例化一個對象,成員方法中的參數會在哪分配內存(棧/堆)?
首先內存總體分為了4個部分,包括 stack segment 、heap segment、code segment 、data segment ;
其中我們程序中用關鍵字new出來的東西都是存放在heap segment;
程序中的局部變數存放在stack segment,這些局部變數是在具體方法執行結束之後,系統自動釋放內存資源(而heap segment中的資源需要java垃圾回收機制來處理);
程序中的方法,是內存中的code segment中的,而且是多個對象 共享一個代碼空間區域;
static靜態變數,需要放在內存中的data segment中,
Java內存模型FAQ 什麼是內存模型
內存模型描述的是程序中各變數(實例域、靜態域和數組元素)之間的關係,以及在實際計算機系統中將變數存儲到內存和從內存取出變數這樣的低層細節。對象最終存儲在內存中,但編譯器、運行庫、處理器或緩存可以有特權定時地在變數的指定內存位置存入或取出變數值。例如,編譯器為了優化一個循環索引變數,可能會選擇把它存儲到一個寄存器中,或者緩存會延遲到一個更適合的時間,才把一個新的變數值存入主存。所有的這些優化是為了幫助實現更高的性能,通常這對於用戶來說是透明的,但是對多處理系統來說,這些複雜的事情可能有時會完全顯現出來。
JMM 允許編譯器和緩存以數據在處理器特定的緩存(或寄存器)和主存之間移動的次序擁有重要的特權,除非程序員已經使用 synchronized 或 final 明確地請求了某些可見性保證。這意味著在缺乏同步的情況下,從不同的線程角度來看,內存的操作是以不同的次序發生的。
與之相對應地,像 C 和 C++ 這些語言就沒有顯示的內存模型 —— 但 C 語言程序繼承了執行程序處理器的內存模型(儘管一個給定體系結構的編譯器可能知道有關底層處理器的內存模型的一些情況,並且保持一致性的一部分責任也落到了該編譯器的頭上)。這意味著並發的 C 語言程序可以在一個,而不能在另一個,處理器體系結構上正確地運行。雖然一開始 JMM 會有些混亂,但這有個很大的好處 —— 根據 JMM 而被正確同步的程序能正確地運行在任何支持 Java 的平台上。
如何查看java虛擬機堆內存的參數值
請確保java_home/bin配置到path環境變數下,因為這些工具都在jdk的bin目錄下
jps(JVM Process Status Tool):JVM機進程狀況工具
用來查看基於HotSpot JVM裡面所有進程的具體狀態, 包括進程ID,進程啟動的路徑等等。與unix上的ps類似,用來顯示本地有許可權的java進程,可以查看本地運行著幾個java程序,並顯示他們的進程號。使用jps時,不需要傳遞進程號做為參數。
Jps也可以顯示遠程系統上的JAVA進程,這需要遠程服務上開啟了jstat服務,以及RMI注及服務,不過常用都是對本對的JAVA進程的查看。
命令格式:jps [ options ] [ hostid ]
常用參數說明:
-m 輸出傳遞給main方法的參數,如果是內嵌的JVM則輸出為null。
-l 輸出應用程序主類的完整包名,或者是應用程序JAR文件的完整路徑。
-v 輸出傳給JVM的參數。
例如:
C:\Users\Administratorjps -lmv
1796 -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m -XX:MaxPermSize=256m
7340 sun.tools.jps.Jps -lmv -Denv.class.path=.;D:\DevTools\VM\jdk1.6.0_31\\lib\dt.jar;D:\DevTools\VM\jdk1.6.0_31\\lib\tools.jar; -Dapplication.home=D:\DevTools\VM\jdk1.6.0_31 -Xms8m
其中pid為1796的是我的eclipse進程,pid為7340的是jps命令本身的進程
jinfo(Configuration Info for Java):JVM配置信息工具
可以輸出並修改運行時的java 進程的opts。用處比較簡單,用於輸出JAVA系統參數及命令行參數
命令格式:jinfo [ options ] [ pid ]
常用參數說明:
-flag 輸出,修改,JVM命令行參數
例如:
C:\Users\Administratorjinfo 1796
將會列印出很多jvm運行時參數信息,由於比較長這裡不再列印出來,可以自己試試,內容一目了然
Jstack(Stack Trace for Java):JVM堆棧跟蹤工具
jstack用於列印出給定的java進程ID或core file或遠程調試服務的Java堆棧信息,如果是在64位機器上,需要指定選項”-J-d64「
命令格式:jstack [ option ] pid
常用參數說明:
-F 當』jstack [-l] pid』沒有相應的時候強制列印棧信息
-l 長列表. 列印關於鎖的附加信息,例如屬於java.util.concurrent的ownable synchronizers列表.
-m 列印java和native c/c++框架的所有棧信息.
-h | -help列印幫助信息
例如:
C:\Users\Administratorjstack 1796
2013-05-22 11:42:38
Full thread dump Java HotSpot(TM) Client VM (20.6-b01 mixed mode):
“Worker-30” prio=6 tid=0x06514c00 nid=0x1018 in Object.wait() [0x056af000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:188)
– locked 0x1ad84a90 (a org.eclipse.core.internal.jobs.WorkerPool)
at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:220)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:50)
……
……
……
……
jstat(JVM statistics Monitoriing Tool):JVM統計信息監視工具
對Java應用程序的資源和性能進行實時的命令行的監控,包括了對Heap size和垃圾回收狀況的監控
命令格式:jstat [ option pid [interval [ s | ms ] [count] ] ]
常用參數說明:
-gcutil 輸出已使用空間佔總空間的百分比
-gccapacity 輸出堆中各個區域使用到的最大和最小空間
例如:每隔1秒監控jvm內存一次,共監控5次
C:\Users\Administratorjstat -gccapacity 1796 1s 5
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 97
C:\Users\Administratorjstat -gcutil 1796 1s 5
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
一些術語的中文解釋:
S0C:年輕代中第一個survivor(倖存區)的容量 (位元組)
S1C:年輕代中第二個survivor(倖存區)的容量 (位元組)
S0U:年輕代中第一個survivor(倖存區)目前已使用空間 (位元組)
S1U:年輕代中第二個survivor(倖存區)目前已使用空間 (位元組)
EC:年輕代中Eden(伊甸園)的容量 (位元組)
EU:年輕代中Eden(伊甸園)目前已使用空間 (位元組)
OC:Old代的容量 (位元組)
OU:Old代目前已使用空間 (位元組)
PC:Perm(持久代)的容量 (位元組)
PU:Perm(持久代)目前已使用空間 (位元組)
YGC:從應用程序啟動到採樣時年輕代中gc次數
YGCT:從應用程序啟動到採樣時年輕代中gc所用時間(s)
FGC:從應用程序啟動到採樣時old代(全gc)gc次數
FGCT:從應用程序啟動到採樣時old代(全gc)gc所用時間(s)
GCT:從應用程序啟動到採樣時gc用的總時間(s)
NGCMN:年輕代(young)中初始化(最小)的大小 (位元組)
NGCMX:年輕代(young)的最大容量 (位元組)
NGC:年輕代(young)中當前的容量 (位元組)
OGCMN:old代中初始化(最小)的大小 (位元組)
OGCMX:old代的最大容量 (位元組)
OGC:old代當前新生成的容量 (位元組)
PGCMN:perm代中初始化(最小)的大小 (位元組)
PGCMX:perm代的最大容量 (位元組)
PGC:perm代當前新生成的容量 (位元組)
S0:年輕代中第一個survivor(倖存區)已使用的占當前容量百分比
S1:年輕代中第二個survivor(倖存區)已使用的占當前容量百分比
E:年輕代中Eden(伊甸園)已使用的占當前容量百分比
O:old代已使用的占當前容量百分比
P:perm代已使用的占當前容量百分比
S0CMX:年輕代中第一個survivor(倖存區)的最大容量 (位元組)
S1CMX :年輕代中第二個survivor(倖存區)的最大容量 (位元組)
ECMX:年輕代中Eden(伊甸園)的最大容量 (位元組)
DSS:當前需要survivor(倖存區)的容量 (位元組)(Eden區已滿)
TT: 持有次數限制
MTT : 最大持有次數限制
jmap( Memory Map for Java):JVM內存映像工具
列印出某個java進程(使用pid)內存內的所有『對象』的情況(如:產生那些對象,及其數量)
命令格式:jmap [ option ] pid
常用參數說明:
-dump:[live,]format=b,file=filename 使用二進位形式輸出jvm的heap內容到文件中, live子選項是可選的,假如指定live選項,那麼只輸出活的對象到文件.
-histo[:live] 列印每個class的實例數目,內存佔用,類全名信息. VM的內部類名字開頭會加上前綴」*」. 如果live子參數加上後,只統計活的對象數量.
-F 強迫.在pid沒有相應的時候使用-dump或者-histo參數. 在這個模式下,live子參數無效.
例如:以二進位形式輸入當前堆內存映像到文件data.hprof中
jmap -dump:live,format=b,file=data.hprof 1796
生成的文件可以使用jhat工具進行分析,在OOM(內存溢出)時,分析大對象,非常有用
通過使用如下參數啟動JVM,也可以獲取到dump文件:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./java_pidpid.hprof
在jvm發生內存溢出時生成內存映像文件
jhat(JVM Heap Analysis Tool):JVM堆轉儲快照分析工具
用於對JAVA heap進行離線分析的工具,他可以對不同虛擬機中導出的heap信息文件進行分析,如LINUX上導出的文件可以拿到WINDOWS上進行分析,可以查找諸如內存方面的問題。
命令格式:jhat dumpfile(jmap生成的文件)
例如:分析jmap導出的內存映像
jhat data.hprof
執行成功後,訪問即可查看內存信息,
MAT(Memory Analyzer Tool):一個基於Eclipse的內存分析工具
官網:
update:
這是eclipse的一個插件,安裝後可以打開xxx.hprof文件,進行分析,比jhat更方便使用,有些時候由於線上xxx.hprof文件過大,直接使用jhat進行初步分析了,可以的話拷貝到本地分析效果更佳。
圖形化監控工具:
在JDK安裝目錄bin下面有兩個可視化監控工具
1. JConsole(Java Monitoring and Management Console) 基於JMX的可視化管理工具。
2. VisualVM(All-in-one Java Troubleshooting Tool)隨JDK發布的最強大的運行監視和故障處理程序。
推薦使用VisualVM,他有很多插件,可以更方便的監控運行時JVM
一個Java對象到底佔多大內存
對象頭
對象頭在32位系統上佔用8bytes,64位系統上佔用16bytes。
實例數據
原生類型(primitive type)的內存佔用如下:
Primitive Type Memory Required(bytes)
boolean 1
byte 1
short 2
char 2
int 4
float 4
long 8
double 8
reference類型在32位系統上每個佔用4bytes, 在64位系統上每個佔用8bytes。
對齊填充
HotSpot的對齊方式為8位元組對齊:
(對象頭 + 實例數據 + padding) % 8等於0且0 = padding 8
指針壓縮
對象佔用的內存大小收到VM參數UseCompressedOops的影響。
1)對對象頭的影響
開啟(-XX:+UseCompressedOops)對象頭大小為12bytes(64位機器)。
static class A {
int a;
}
原創文章,作者:O2L89,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/127834.html