當前位置:首頁 » 硬碟大全 » jvm緩存基本類型數值范圍
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

jvm緩存基本類型數值范圍

發布時間: 2022-10-09 13:02:56

『壹』 java的基本數據類型有哪些

四種八類:

基本數據類型

整數類型:

byte:位元組佔用 1位元組 8位,用來表達最小的數據單位,儲存數據長度為 正負 127;

short:位元組佔用 2位元組 16位,儲存數值長度為 -32768-32767

int:位元組佔用 4位元組 32位,最為常用的整數類型,儲存長度為,-2^31-1~2^31 (21 億)

long:位元組佔用 8位元組 64位,當到達int數值極限時使用,儲存長度為 看圖片:


浮點數類型:

float:單精度浮點型 32位 取值范圍 3.4e-38~3.4e-38

double:雙精度浮點型 64位 ,java中默認的浮點類型 取值范圍 1.7e-308~1.7e-308

字元類型:

char:16位 ,java字元使用Unicode編碼;

布爾類型

boolean : true 真 和 false 假

引用數據類型:

類 class

介面 interface

數組

『貳』 JVM內存最大能調多大

分析了當前比較流行的幾個不同公司不同版本JVM的最大內存,得出來的結果如下: 公司JVM版本 最大內存(兆)client 最大內存(兆)server SUN 1.5.x 1492 1520 SUN 1.5.5(Linux) 2634 2660 SUN 1.4.2 1564 1564 SUN 1.4.2(Linux) 1900 1260 IBM 1.4.2(Linux) 2047 N/A BEA JRockit 1.5 (U3) 1909 1902 除非特別說明,否則JVM版本都運行在Windows操作系統下 通過這個表想說明的是,如果你的機器的內存太多的話,只能通過多運行幾個實例來提供機器的利用率了,例如跑Tomcat,你可以多裝幾個Tomcat並做集群,依此類推。 堆(Heap)和非堆(Non-heap)內存按照官方的說法:「Java 虛擬機具有一個堆,堆是運行時數據區域,所有類實例和數組的內存均從此處分配。堆是在 Java 虛擬機啟動時創建的。」「在JVM中堆之外的內存稱為非堆內存(Non-heap memory)」。可以看出JVM主要管理兩種類型的內存:堆和非堆。簡單來說堆就是Java代碼可及的內存,是留給開發人員使用的;非堆就是JVM留給自己用的,所以方法區、JVM內部處理或優化所需的內存(如JIT編譯後的代碼緩存)、每個類結構(如運行時常數池、欄位和方法數據)以及方法和構造方法的代碼都在非堆內存中。 堆內存分配JVM初始分配的內存由-Xms指定,默認是物理內存的1/64;JVM最大分配的內存由-Xmx指定,默認是物理內存的1/4。默認空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆內存大於70% 時,JVM會減少堆直到-Xms的最小限制。因此伺服器一般設置-Xms、-Xmx相等以避免在每次GC 後調整堆的大小。 非堆內存分配JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。 JVM內存限制(最大值)首先JVM內存限制於實際的最大物理內存(廢話!呵呵),假設物理內存無限大的話,JVM內存的最大值跟操作系統有很大的關系。簡單的說就32位處理器雖然可控內存空間有4GB,但是具體的操作系統會給一個限制,這個限制一般是2GB-3GB(一般來說Windows系統下為1.5G-2G,Linux系統下為2G-3G),而64bit以上的處理器就不會有限制了。 所以說設置VM參數導致程序無法啟動主要有以下幾種原因: 1) 參數中-Xms的值大於-Xmx,或者-XX:PermSize的值大於-XX:MaxPermSize;2) -Xmx的值和-XX:MaxPermSize的總和超過了JVM內存的最大限制,比如當前操作系統最大內存限制,或者實際的物理內存等等。

『叄』 JAVA中數據類型有幾種,請舉例說明

JAVA數據類型分基本數據類型和引用數據類型。

基本數據類型

Java裡麵包含8個基本數據類型,分別是:
boolean、byte、char、short、int、float、douboe、long

byte 位元組
byte是JAVA中最小的數據類型,它在內存中佔8位(8個bit),取值范圍從-128到127
賦值:byte I = 127

short 短整型
short類型在內存中佔2個位元組,取值范圍從 -32768到32767
賦值:short i = 32767;

char 字元型
char類型在內存中佔2個位元組。表示一個字元,也可以使用ASCII碼范圍內的值來給char型的變數賦值。由於字元在內存中的取值不存在負數范圍,所有取值范圍從 0 到 65535
賦值:char i = 『a』; 或者 char i = 97;

int 整型
int型在內存中佔4個位元組。取值范圍從 -2147483648 到 2147483647
賦值:int i = 10;

float 單精度浮點型
float型在內存中佔4個位元組。取值范圍從 -3.4E38 到 3.4E38
賦值:float i = 1.0f;

long 長整型
long型在內存中佔8個位元組。取值范圍從 -9223372036854775808 到 9223372036854775807

double 雙精度浮點型
double 型在內存中佔8個位元組。取值范圍從 -1.7E308 到 1.7E308

boolean 布爾型
boolean類型只有兩個值:true和false。

基本數據類型的相互轉換

轉型規則

JAVA中所有的數字變數都是有符號(正負)的。
JAVA不允許類型的隨意轉換。只有數字變數可以進行轉換,但是不能隨意。
帶有小數點的數字變數默認都為double型。定義float型必須進行強制類型轉換。
所佔位元組數小的數字型變數賦值給所佔位元組數比它大的類型時不用強制類型轉換,此時是自動轉型。
int型變數賦值給char型變數時,JVM會以int型變數值到ASCII碼表中查找出所對應的字元,再賦值給char型變數。反之也是。但是遵循第4條規則。
初始化簡單數據類型時要注意賦值的范圍,超出則會產生編譯錯誤。

基本數據類型默認初值

類型 初始值

boolean false
byte 0
char 0
short 0
int 0
float 0.0
double 0.0
long 0
基本數據類型默認初值表

引用數據類型
JAVA中,非簡單數據類型的類型都是引用數據類型。

『肆』 64位的JVM當中,int的長度是多少

Java數據類型與平台無關
不像C++。
是統一由JVM適配的,int類型為32位,即4個位元組

『伍』 Java代碼如何優化

1. 盡量在合適的場合使用單例
使用單例可以減輕載入的負擔,縮短載入的時間,提高載入的效率,但並不是所有地方都適用於單例,簡單來說,單例主要適用於以下三個方面:
第一,控制資源的使用,通過線程同步來控制資源的並發訪問;
第二,控制實例的產生,以達到節約資源的目的;
第三,控制數據共享,在不建立直接關聯的條件下,讓多個不相關的進程或線程之間實現通信。
2. 盡量避免隨意使用靜態變數
要知道,當某個對象被定義為stataic變數所引用,那麼gc通常是不會回收這個對象所佔有的內存
3. 盡量避免過多過常的創建Java對象
盡量避免在經常調用的方法,循環中new對象,由於系統不僅要花費時間來創建對象,而且還要花時間對這些對象進行垃圾回收和處理,在我們可以控制的范圍內,最大限度的重用對象,最好能用基本的數據類型或數組來替代對象。
4. 盡量使用final修飾符
帶有final修飾符的類是不可派生的。在Java核心API中,有許多應用final的例子,例如java.lang.String.為String類指定final防止了使用者覆蓋length()方法。另外,如果一個類是final的,則該類所有方法都是final的。Java編譯器會尋找機會內聯(inline)所有的final方法(這和具體的編譯器實現有關)。此舉能夠使性能平均提高50%.
5. 盡量使用局部變數
調用方法時傳遞的參數以及在調用中創建的臨時變數都保存在棧(Stack)中,速度較快。其他變數,如靜態變數、實例變數等,都在堆(Heap)中創建,速度較慢。
6. 盡量處理好包裝類型和基本類型兩者的使用場所
雖然包裝類型和基本類型在使用過程中是可以相互轉換,但它們兩者所產生的內存區域是完全不同的,基本類型數據產生和處理都在棧中處理,包裝類型是對象,是在堆中產生實例。
在集合類對象,有對象方面需要的處理適用包裝類型,其他的處理提倡使用基本類型。
7. 慎用synchronized,盡量減小synchronize的方法
都知道,實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。synchronize方法被調用時,直接會把當前對象鎖 了,在方法執行完之前其他線程無法調用當前對象的其他方法。所以synchronize的方法盡量小,並且應盡量使用方法同步代替代碼塊同步。
8. 盡量使用StringBuilder和StringBuffer進行字元串連接
這個就不多講了。
9. 盡量不要使用finalize方法
實際上,將資源清理放在finalize方法中完成是非常不好的選擇,由於GC的工作量很大,尤其是回收Young代內存時,大都會引起應用程序暫停,所以再選擇使用finalize方法進行資源清理,會導致GC負擔更大,程序運行效率更差。
10. 盡量使用基本數據類型代替對象
String str = "hello";
上面這種方式會創建一個"hello"字元串,而且JVM的字元緩存池還會緩存這個字元串;
String str = new String("hello");
此時程序除創建字元串外,str所引用的String對象底層還包含一個char[]數組,這個char[]數組依次存放了h,e,l,l,o
11. 單線程應盡量使用HashMap、ArrayList
HashTable、Vector等使用了同步機制,降低了性能。
12. 盡量合理的創建HashMap
當你要創建一個比較大的hashMap時,充分利用另一個構造函數
public HashMap(int initialCapacity, float loadFactor)
避免HashMap多次進行了hash重構,擴容是一件很耗費性能的事,在默認中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能准確的估計你所需要的最佳大小,同樣的Hashtable,Vectors也是一樣的道理。
13. 盡量減少對變數的重復計算
並且在循環中應該避免使用復雜的表達式,在循環中,循環條件會被反復計算,如果不使用復雜表達式,而使循環條件值不變的話,程序將會運行的更快。
14. 盡量避免不必要的創建
15. 盡量在finally塊中釋放資源
程序中使用到的資源應當被釋放,以避免資源泄漏。這最好在finally塊中去做。不管程序執行的結果如何,finally塊總是會執行的,以確保資源的正確關閉。
16. 盡量使用移位來代替'a/b'的操作
"/"是一個代價很高的操作,使用移位的操作將會更快和更有效
17.盡量使用移位來代替'a*b'的操作
同樣的,對於'*'操作,使用移位的操作將會更快和更有效
18. 盡量確定StringBuffer的容量
StringBuffer 的構造器會創建一個默認大小(通常是16)的字元數組。在使用中,如果超出這個大小,就會重新分配內存,創建一個更大的數組,並將原先的數組復制過來,再 丟棄舊的數組。在大多數情況下,你可以在創建 StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高性能。
19. 盡量早釋放無用對象的引用
大部分時,方法局部引用變數所引用的對象 會隨著方法結束而變成垃圾,因此,大部分時候程序無需將局部,引用變數顯式設為null.
20. 盡量避免使用二維數組
二維數據佔用的內存空間比一維數組多得多,大概10倍以上。
21. 盡量避免使用split
除非是必須的,否則應該避免使用split,split由於支持正則表達式,所以效率比較低,如果是頻繁的幾十,幾百萬的調用將會耗費大量資源,如果確實需 要頻繁的調用split,可以考慮使用apache的StringUtils.split(string,char),頻繁split的可以緩存結果。
22. ArrayList & LinkedList
一 個是線性表,一個是鏈表,一句話,隨機查詢盡量使用ArrayList,ArrayList優於LinkedList,LinkedList還要移動指 針,添加刪除的操作LinkedList優於ArrayList,ArrayList還要移動數據,不過這是理論性分析,事實未必如此,重要的是理解好2 者得數據結構,對症下葯。
23. 盡量使用System.array ()代替通過來循環復制數組
System.array() 要比通過循環來復制數組快的多
24. 盡量緩存經常使用的對象
盡可能將經常使用的對象進行緩存,可以使用數組,或HashMap的容器來進行緩存,但這種方式可能導致系統佔用過多的緩存,性能下降,推薦可以使用一些第三方的開源工具,如EhCache,Oscache進行緩存,他們基本都實現了FIFO/FLU等緩存演算法。
25. 盡量避免非常大的內存分配
有時候問題不是由當時的堆狀態造成的,而是因為分配失敗造成的。分配的內存塊都必須是連續的,而隨著堆越來越滿,找到較大的連續塊越來越困難。
26. 慎用異常
當創建一個異常時,需要收集一個棧跟蹤(stack track),這個棧跟蹤用於描述異常是在何處創建的。構建這些棧跟蹤時需要為運行時棧做一份快照,正是這一部分開銷很大。當需要創建一個 Exception 時,JVM 不得不說:先別動,我想就您現在的樣子存一份快照,所以暫時停止入棧和出棧操作。棧跟蹤不只包含運行時棧中的一兩個元素,而是包含這個棧中的每一個元素。
如 果您創建一個 Exception ,就得付出代價。好在捕獲異常開銷不大,因此可以使用 try-catch 將核心內容包起來。從技術上講,您甚至可以隨意地拋出異常,而不用花費很大的代價。招致性能損失的並不是 throw 操作--盡管在沒有預先創建異常的情況下就拋出異常是有點不尋常。真正要花代價的是創建異常。幸運的是,好的編程習慣已教會我們,不應該不管三七二十一就 拋出異常。異常是為異常的情況而設計的,使用時也應該牢記這一原則。
(1)。 用Boolean.valueOf(boolean b)代替new Boolean()
包裝類的內存佔用是很恐怖的,它是基本類型內存佔用的N倍(N>2),同時new一個對象也是性能的消耗。
(2)。 用Integer.valueOf(int i)代替new Integer()
和Boolean類似,java開發中使用Integer封裝int的場合也非常多,並且通常用int表示的數值都非常小。SUN SDK中對Integer的實例化進行了優化,Integer類緩存了-128到127這256個狀態的Integer,如果使用 Integer.valueOf(int i),傳入的int范圍正好在此內,就返回靜態實例。這樣如果我們使用Integer.valueOf代替new Integer的話也將大大降低內存的佔用。
(3)。 用StringBuffer的append方法代替"+"進行字元串相加。
這個已經被N多人說過N次了,這個就不多說了。
(4)。 避免過深的類層次結構和過深的方法調用。
因為這兩者都是非常佔用內存的(特別是方法調用更是堆棧空間的消耗大戶)。
(5)。 變數只有在用到它的時候才定義和實例化。
這是初學者最容易犯的錯,合理的使用變數,並且只有在用到它的時候才定義和實例化,能有效的避免內存空間和執行性能上的浪費,從而提高了代碼的效率。
(6)。 避免在循環體中聲明創建對象,即使該對象佔用內存空間不大。
這種情況在我們的實際應用中經常遇到,而且我們很容易犯類似的錯誤
採用上面的第二種編寫方式,僅在內存中保存一份對該對象的引用,而不像上面的第一種編寫方式中代碼會在內存中產生大量的對象引用,浪費大量的內存空間,而且增大了垃圾回收的負荷。因此在循環體中聲明創建對象的編寫方式應該盡量避免。
(7)。 如果if判斷中多個條件用'||'或者'&&'連接,請將出現頻率最高的條件放在表達式最前面。
這個小技巧往往能有效的提高程序的性能,尤其是當if判斷放在循環體裡面時,效果更明顯。
1.JVM管理兩種類型的內存:堆內存(heap),棧內存(stack),堆內在主要用來存儲程序在運行時創建或實例化的對象與變數。而棧內存則是用來存儲程序代碼中聲明為靜態(static)(或非靜態)的方法。
2.JVM中對象的生命周期,創建階段,應用階段,不可視階段,不可到達階段,可收集階段,終結階段,釋放階段
3.避免在循環體中創建對象,即使該對象點用內存空間不大。
4.軟引用的主要特點是具有較強的引用功能。只有當內存不夠的時候,才回收這類內存,因此在內存足夠的時候,它們通常不被回收。它可以用於實現一些常用資源的緩存,實現Cache的功能
5.弱引用對象與Soft引用對象最大不同就在於:GC在進行回收時,需要通過演算法檢查是否回收Soft引用對象,而對於Weak引用對象,GC總是進行回收。
6.共享靜態變數存儲空間
7.有時候我們為了提高系統性能,避免重復耗時的操作,希望能夠重用一些創建完成的對象,利用對象池實現。類似JDBC連接池。
8.瞬間值,序列化對象大變數時,如果此大變數又沒有用途,則使用transient聲明,不序列化此變數。同時網路傳輸中也不傳輸。
9.不要提前創建對象
10 .(1)最基本的建議就是盡早釋放無用對象的引用
A a = new A();
a = null; //當使用對象a之後主動將其設置為空
(2)盡量少用finalize函數。
(3) 如果需要使用經常用到的圖片展,可以使用軟引用。
(4) 注意集合數據類型,包括數組,樹等數據,這些數據結構對GC來說,回收更為復雜,
(5) 盡量避免在類的默認構造器中創建,初始化大量的對象,防止在調用其自類的構造器時造成不必要的內存資源浪費。
(6) 盡量避免強制系統做垃圾內存回收。
(7) 盡量避免顯式申請數組空間。
(8) 盡量在合適的場景下使用對象池技術以提高系統性能,縮減系統內存開銷。
11.當做數組拷貝操作時,採用System.array()方法完成拷貝操作要比採用循環的辦法完成數組拷貝操作效率高
12. 盡量避免在循環體中調用方法,因為方法調用是比較昂貴的。
13. 盡量避免在循環體中使用try-catch 塊,最好在循環體外使用try--catch塊以提高系統性能。
14. 在多重循環中,如果有可能,盡量將最長的循環放在最內層,最短的循環放在最外層,以減少循環層間的變換次數。
15. 在需要線程安全的情況下,使用List list = Collections.synchronizedList(new ArrayList());
16. 如果預知長度,就設置ArrayList的長度。
17. ArrayList 與 LinkedList 選擇,熟悉底層的實現原理,選擇適當的容器。
18. 字元串累加採用StringBuffer.
19. 系統I/O優化,採用緩沖和壓縮技術。優化性能。
20. 避免在類在構造器的初始化其他類
21 盡量避免在構造中對靜態變數做賦值操作
22. 不要在類的構造器中創建類的實例
23. 組合優化繼承
24. 最好通過Class.forname() 動態的裝載類
25. JSP優化,採用out 對象中的print方法代替println()方法
26 .採用ServletOutputStream 對象代替JSPWriter對象
27. 採用適當的值初始化out 對象緩沖區的大小
28. 盡量採用forward()方法重定向新的JSP
29. 利用線程池技術處理客戶請求
30.Servlet優化
(1) 通過init()方法來緩存一些靜態數據以提高應用性能。
(2) 用print() 方法取代println()方法。
(3) 用ServletOutputStream 取代 PrintWriter.
(4) 盡量縮小同步代碼數量
31. 改善Servlet應用性能的方法
(1)不要使用SingleThreadModel
(2)使用線程池ThreadPool
32. EJB優化
實體EJB:
(1)實體EJB中常用數據緩存與釋放
(2)採用延遲載入的方式裝載關聯數據
(3)盡可能地應用CMP類型實體EJB
(4)直接採用JDBC技術處理大型數據
33. 優化JDBC連接
(1)設置合適的預取行值
(2)採用連接池技術
(3)全合理應用事務
(4)選擇合適的事務隔離層與及時關閉連接對象
34. PreparedStatemetn只編譯解析一次,而Statement每次都編譯解析。
35. 盡可能地做批處理更新
36. 通過採用合適的getXXX方法提高系統性能
37. 採用設計模式。

『陸』 JVM原理是什麼

首先這里澄清兩個概念:JVM實例和JVM執行引擎實例,JVM實例對應了一個獨立運行的Java程序,而JVM執行引擎實例則對應了屬於用戶運行程序的線程;也就是JVM實例是進程級別,而執行引擎是線程級別的。JVM是什麼?—JVM的生命周期JVM實例的誕生:當啟動一個Java程序時,一個JVM實例就產生了,任何一個擁有publicstaticvoidmain(String[]args)函數的class都可以作為JVM實例運行的起點,既然如此,那麼JVM如何知道是運行classA的main而不是運行classB的main呢?這就需要顯式的告訴JVM類名,也就是我們平時運行Java程序命令的由來,如JavaclassAhelloworld,這里Java是告訴os運行SunJava2SDK的Java虛擬機,而classA則指出了運行JVM所需要的類名。JVM實例的運行:main()作為該程序初始線程的起點,任何其他線程均由該線程啟動。JVM內部有兩種線程:守護線程和非守護線程,main()屬於非守護線程,守護線程通常由JVM自己使用,Java程序也可以標明自己創建的線程是守護線程。JVM實例的消亡:當程序中的所有非守護線程都終止時,JVM才退出;若安全管理器允許,程序也可以使用Runtime類或者System.exit()來退出。JVM是什麼?—JVM的體系結構粗略分來,JVM的內部體系結構分為三部分,分別是:類裝載器(ClassLoader)子系統,運行時數據區,和執行引擎。下面將先介紹類裝載器,然後是執行引擎,最後是運行時數據區1、類裝載器,顧名思義,就是用來裝載.class文件的。JVM的兩種類裝載器包括:啟動類裝載器和用戶自定義類裝載器,啟動類裝載器是JVM實現的一部分,用戶自定義類裝載器則是Java程序的一部分,必須是ClassLoader類的子類。(下面所述情況是針對SunJDK1.2)動類裝載器:只在系統類(JavaAPI的類文件)的安裝路徑查找要裝入的類用戶自定義類裝載器:系統類裝載器:在JVM啟動時創建,用來在CLASSPATH目錄下查找要裝入的類其他用戶自定義類裝載器:這里有必要先說一下ClassLoader類的幾個方法,了解它們對於了解自定義類裝載器如何裝載.class文件至關重要。(Stringname,bytedata[],intoffset,intlength) (Stringname,bytedata[],intoffset,intlength,);(Stringname) (Classc) defineClass用來將二進制class文件(新類型)導入到方法區,也就是這里指的類是用戶自定義的類(也就是負責裝載類)findSystemClass通過類型的全限定名,先通過系統類裝載器或者啟動類裝載器來裝載,並返回Class對象。ResolveClass:讓類裝載器進行連接動作(包括驗證,分配內存初始化,將類型中的符號引用解析為直接引用),這里涉及到Java命名空間的問題,JVM保證被一個類裝載器裝載的類所引用的所有類都被這個類裝載器裝載,同一個類裝載器裝載的類之間可以相互訪問,但是不同類裝載器裝載的類看不見對方,從而實現了有效的屏蔽。2、執行引擎:它或者在執行位元組碼,或者執行本地方法要說執行引擎,就不得不的指令集,每一條指令包含一個單位元組的操作碼,後面跟0個或者多個操作數。(一)指令集以棧為設計中心,而非以寄存器為中心這種指令集設計如何滿足Java體系的要求:平台無關性:以棧為中心使得在只有很少register的機器上實現Java更便利compiler一般採用stack向連接優化器傳遞編譯的中間結果,若指令集以stack為基礎,則有利於運行時進行的優化工作與執行即時編譯或者自適應優化的執行引擎結合,通俗的說就是使編譯和運行用的數據結構統一,更有利於優化的開展。網路移動性:class文件的緊湊性。安全性:指令集中絕大部分操作碼都指明了操作的類型。(在裝載的時候使用數據流分析期進行一次性驗證,而非在執行每條指令的時候進行驗證,有利於提高執行速度)。(二)執行技術主要的執行技術有:解釋,即時編譯,自適應優化、晶元級直接執行其中解釋屬於第一代JVM,即時編譯JIT屬於第二代JVM,自適應優化(目前Sun的HotspotJVM採用這種技術)則吸取第一代JVM和第二代JVM的經驗,採用兩者結合的方式自適應優化:開始對所有的代碼都採取解釋執行的方式,並監視代碼執行情況,然後對那些經常調用的方法啟動一個後台線程,將其編譯為本地代碼,並進行仔細優化。若方法不再頻繁使用,則取消編譯過的代碼,仍對其進行解釋執行。3、運行時數據區:主要包括:方法區,堆,Java棧,PC寄存器,本地方法棧(1)方法區和堆由所有線程共享堆:存放所有程序在運行時創建的對象方法區:當JVM的類裝載器載入.class文件,並進行解析,把解析的類型信息放入方法區。(2)Java棧和PC寄存器由線程獨享,在新線程創建時間里(3)本地方法棧:存儲本地方法調用的狀態上邊總體介紹了運行時數據區的主要內容,下邊進行詳細介紹,要介紹數據區,就不得不說明JVM中的數據類型。JVM中的數據類型:JVM中基本的數據單元是word,而word的長度由JVM具體的實現者來決定數據類型包括基本類型和引用類型,(1)基本類型包括:數值類型(包括除boolean外的所有的Java基本數據類型),boolean(在JVM中使用int來表示,0表示false,其他int值均表示true)和returnAddress(JVM的內部類型,用來實現finally子句)。(2)引用類型包括:數組類型,類類型,介面類型前邊講述了JVM中數據的表示,下面讓我們輸入到JVM的數據區首先來看方法區:上邊已經提到,方法區主要用來存儲JVM從class文件中提取的類型信息,那麼類型信息是如何存儲的呢?眾所周知,Java使用的是大端序(big?endian:即低位元組的數據存儲在高位內存上,如對於1234,12是高位數據,34為低位數據,則Java中的存儲格式應該為12存在內存的低地址,34存在內存的高地址,x86中的存儲格式與之相反)來存儲數據,這實際上是在class文件中數據的存儲格式,但是當數據倒入到方法區中時,JVM可以以任何方式來存儲它。類型信息:包括class的全限定名,class的直接父類,類類型還是介面類型,類的修飾符(public,等),所有直接父介面的列表,Class對象提供了訪問這些信息的窗口(可通過Class.forName(「」)或instance.getClass()獲得),下面是Class的方法,相信大家看了會恍然大悟,(原來如此J)getName(),getSuperClass(),isInterface(),getInterfaces(),getClassLoader();static變數作為類型信息的一部分保存指向ClassLoader類的引用:在動態連接時裝載該類中引用的其他類指向Class類的引用:必然的,上邊已述該類型的常量池:包括直接常量(String,integer和floatpoint常量)以及對其他類型、欄位和方法的符號引用(注意:這里的常量池並不是普通意義上的存儲常量的地方,這些符號引用可能是我們在編程中所接觸到的變數),由於這些符號引用,使得常量池成為Java程序動態連接中至關重要的部分欄位信息:普通意義上的類型中聲明的欄位方法信息:類型中各個方法的信息編譯期常量:指用final聲明或者用編譯時已知的值初始化的類變數class將所有的常量復制至其常量池或者其位元組碼流中。方法表:一個數組,包括所有它的實例可能調用的實例方法的直接引用(包括從父類中繼承來的)除此之外,若某個類不是抽象和本地的,還要保存方法的位元組碼,操作數棧和該方法的棧幀,異常表。舉例:classLava{ privateintspeed=5; voidflow(){} classVolcano{ publicstaticvoidmain(String[]args){ Lavalava=newLava(); lava.flow(); } } 運行命令JavaVolcano;(1)JVM找到Volcano.class倒入,並提取相應的類型信息到方法區。通過執行方法區中的位元組碼,JVM執行main()方法,(執行時會一直保存指向Vocano類的常量池的指針)(2)Main()中第一條指令告訴JVM需為列在常量池第一項的類分配內存(此處再次說明了常量池並非只存儲常量信息),然後JVM找到常量池的第一項,發現是對Lava類的符號引用,則檢查方法區,看Lava類是否裝載,結果是還未裝載,則查找「Lava.class」,將類型信息寫入方法區,並將方法區Lava類信息的指針來替換Volcano原常量池中的符號引用,即用直接引用來替換符號引用。(3)JVM看到new關鍵字,准備為Lava分配內存,根據Volcano的常量池的第一項找到Lava在方法區的位置,並分析需要多少對空間,確定後,在堆上分配空間,並將speed變數初始為0,並將lava對象的引用壓到棧中(4)調用lava的flow()方法好了,大致了解了方法區的內容後,讓我們來看看堆Java對象的堆實現:Java對象主要由實例變數(包括自己所屬的類和其父類聲明的)以及指向方法區中類數據的指針,指向方法表的指針,對象鎖(非必需),等待集合(非必需),GC相關的數據(非必需)(主要視GC演算法而定,如對於標記並清除演算法,需要標記對象是否被引用,以及是否已調用finalize()方法)。那麼為什麼Java對象中要有指向類數據的指針呢?我們從幾個方面來考慮首先:當程序中將一個對象引用轉為另一個類型時,如何檢查轉換是否允許?需用到類數據其次:動態綁定時,並不是需要引用類型,而是需要運行時類型,這里的迷惑是:為什麼類數據中保存的是實際類型,而非引用類型?這個問題先留下來,我想在後續的讀書筆記中應該能明白指向方法表的指針:這里和C++的VTBL是類似的,有利於提高方法調用的效率對象鎖:用來實現多個線程對共享數據的互斥訪問等待集合:用來讓多個線程為完成共同目標而協調功過。(注意Object類中的wait(),notify(),notifyAll()方法)。Java數組的堆實現:數組也擁有一個和他們的類相關聯的Class實例,具有相同dimension和type的數組是同一個類的實例。數組類名的表示:如[[LJava/lang/Object表示Object[][],[I表示int[],[[[B表示byte[][][]至此,堆已大致介紹完畢,下面來介紹程序計數器和Java棧程序計數器:為每個線程獨有,在線程啟動時創建,若thread執行Java方法,則PC保存下一條執行指令的地址。若thread執行native方法,則Pc的值為undefinedJava棧:Java棧以幀為單位保存線程的運行狀態,Java棧只有兩種操作,幀的壓棧和出棧。每個幀代表一個方法,Java方法有兩種返回方式,return和拋出異常,兩種方式都會導致該方法對應的幀出棧和釋放內存。幀的組成:局部變數區(包括方法參數和局部變數,對於instance方法,還要首先保存this類型,其中方法參數按照聲明順序嚴格放置,局部變數可以任意放置),操作數棧,幀數據區(用來幫助支持常量池的解析,正常方法返回和異常處理)。本地方法棧:依賴於本地方法的實現,如某個JVM實現的本地方法借口使用C連接模型,則本地方法棧就是C棧,可以說某線程在調用本地方法時,就進入了一個不受JVM限制的領域,也就是JVM可以利用本地方法來動態擴展本身。相信大家都明白JVM是什麼了吧。原文鏈接: http://www.cnblogs.com/chenzhao/archive/2011/08/14/2137713.html

『柒』 java基本數據類型有哪些

Java的基本數據類型分為:整數類型、浮點類型、字元類型、布爾類型這四個類型。

1、整數類型

整數類型變數用來表示整數的數據類型。整數類型又分為位元組型(byte)、短整型(short)、整型(int)、長整型(long)這四種。

4、布爾類型

布爾類型是表示邏輯值的基本數據類型。boolean常量有「真」和「假」這兩個狀態。一般用true表示「真」、false表示「假」。它的定義方法是在變數名前加上類型關鍵字boolean。

『捌』 如何查看java虛擬機堆內存的參數值

今天在載入一幅圖片時,eclipse報出如下錯誤:
「Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 」
google了一下原來是圖片太大了。可以設置jvm堆的最大值來解決。

首先, 打開Eclipse軟體,選擇菜單欄run,在二級菜單中選擇 Debug Configurations,然後:在彈出的窗口中選擇(x)=arguments選項卡,VM arguments中輸入所需要的內存最大佔用量,比如輸入-Xmx800m即可。

以下詳細的介紹下jvm的幾個參數:
「MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) space remains.」意思是說當前只有小於5%的非堆內存是空閑的。所以我們只要將這個值設置大一些就可以了。
提示中給出了設置的參數:
-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
這里有幾個問題:
1. 各個參數的含義什麼?
2. 為什麼有的機器我將-Xmx和-XX:MaxPermSize都設置為512M之後Eclipse可以啟動,而有些機器無法啟動?
3. 為何將上面的參數寫入到eclipse.ini文件Eclipse沒有執行對應的設置?
下面我們一一進行回答
1. 各個參數的含義什麼?
參數中-vmargs的意思是設置JVM參數,所以後面的其實都是JVM的參數了,我們首先了解一下JVM內存管理的機制,然後再解釋每個參數代表的含義。
堆(Heap)和非堆(Non-heap)內存
按照官方的說法:「Java 虛擬機具有一個堆,堆是運行時數據區域,所有類實例和數組的內存均從此處分配。堆是在 Java 虛擬機啟動時創建的。」「在JVM中堆之外的內存稱為非堆內存(Non-heap memory)」。可以看出JVM主要管理兩種類型的內存:堆和非堆。簡單來說堆就是Java代碼可及的內存,是留給開發人員使用的;非堆就是JVM留給自己用的,所以方法區、JVM內部處理或優化所需的內存(如JIT編譯後的代碼緩存)、每個類結構(如運行時常數池、欄位和方法數據)以及方法和構造方法的代碼都在非堆內存中。
堆內存分配
JVM初始分配的內存由-Xms指定,默認是物理內存的1/64;JVM最大分配的內存由-Xmx指定,默認是物理內存的1/4。默認空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆內存大於70% 時,JVM會減少堆直到-Xms的最小限制。因此伺服器一般設置-Xms、-Xmx相等以避免在每次GC 後調整堆的大小。
非堆內存分配
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。
JVM內存限制(最大值)
首先JVM內存限制於實際的最大物理內存(廢話!呵呵),假設物理內存無限大的話,JVM內存的最大值跟操作系統有很大的關系。簡單的說就32位處理器雖然可控內存空間有4GB,但是具體的操作系統會給一個限制,這個限制一般是2GB-3GB(一般來說Windows系統下為1.5G-2G,Linux系統下為2G-3G),而64bit以上的處理器就不會有限制了。
2. 為什麼有的機器我將-Xmx和-XX:MaxPermSize都設置為512M之後Eclipse可以啟動,而有些機器無法啟動?
通過上面對JVM內存管理的介紹我們已經了解到JVM內存包含兩種:堆內存和非堆內存,另外JVM最大內存首先取決於實際的物理內存和操作系統。所以說設置VM參數導致程序無法啟動主要有以下幾種原因:
1) 參數中-Xms的值大於-Xmx,或者-XX:PermSize的值大於-XX:MaxPermSize;
2) -Xmx的值和-XX:MaxPermSize的總和超過了JVM內存的最大限制,比如當前操作系統最大內存限制,或者實際的物理內存等等。說到實際物理內存這里需要說明一點的是,如果你的內存是1024MB,但實際系統中用到的並不可能是1024MB,因為有一部分被硬體佔用了。
3. 為何將上面的參數寫入到eclipse.ini文件Eclipse沒有執行對應的設置?
那為什麼同樣的參數在快捷方式或者命令行中有效而在eclipse.ini文件中是無效的呢?這是因為我們沒有遵守eclipse.ini文件的設置規則:
參數形如「項 值」這種形式,中間有空格的需要換行書寫,如果值中有空格的需要用雙引號包括起來。比如我們使用-vm C:\Java\jre1.6.0\bin\javaw.exe參數設置虛擬機,在eclipse.ini文件中要寫成這樣:
-vm
C:\Java\jre1.6.0\bin\javaw.exe
按照上面所說的,最後參數在eclipse.ini中可以寫成這個樣子:
-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=64M
-XX:MaxPermSize=128M
實際運行的結果可以通過Eclipse中「Help」-「About Eclipse SDK」窗口裡面的「Configuration Details」按鈕進行查看。
另外需要說明的是,Eclipse壓縮包中自帶的eclipse.ini文件內容是這樣的:
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
-vmargs
-Xms40m
-Xmx256m
其中–launcher.XXMaxPermSize(注意最前面是兩個連接線)跟-XX:MaxPermSize參數的含義基本是一樣的,我覺得唯一的區別就是前者是eclipse.exe啟動的時候設置的參數,而後者是eclipse所使用的JVM中的參數。其實二者設置一個就可以了,所以這里可以把–launcher.XXMaxPermSize和下一行使用#注釋掉。

『玖』 java中的數據類型

java中的數據類型分兩大類分別是基本類型和引用數據類型。

一、基本類型

1)Java中的數據類型有八種,即基本類型。具體如下:

數據類型 位數 取值范圍:

Boolean 1 True|False

Byte 8 -128~127

Short 16 -32768~32767

Int 32 -2e31~2e31-1

Long 64 -2e63~2e63-1

Float 32 略

Double 64 略

Char 16 0~65535

『 /u0000』 ~』uFFFF『

二、引用數據類型

1)定義一個byte變數 如:byte b= -256;

由於-256超出了』Byte』的取值范圍,所以要使程序不報錯,有一下幾種解決方法:

A:更改變數的數據類型(如:將byte改為int);

B:更改變數名的賦值,使其包括在變數的數據類型的值域內;

C:進行強制轉換:如: byte b=(byte)-256:

『進行強制轉換後,雖然程序不在報錯,但是有可能會使原值的精度收到影響』

D:定義一個浮點類型數時,記得要在數值的後面加上「f」或「F」。(如:Float f=10000.0f;)

E:若定義 Char c=a;定義 int n=c;則輸出的n值為「a「的ASCII值,即97。

2)引用數據類型的定義

A:對象都是引用數據類型

B:應用類型使用NEW調用構造方法進行賦值

C:在Java中,除了基本數據類型以外,其餘的全都屬於引用數據類型, 如:

a:API中的類,如String,File等;

b:數據;

c:自定義的類,如Cars,Student

d:對象全部是引用數據類型。

(9)jvm緩存基本類型數值范圍擴展閱讀

其他數據類型:

在java中,String本身也提供了很多的方法供我們使用:

獲取到指定索引位置的字元:char c = 字元串.charAt(索引位置);

獲取到指定索引位置的字元:char c = 字元串.charAt(索引位置);

獲取第一次出現在字元串中的字元:int index = 字元串.index('a');

獲取在字元串中字元的索引位置:int index = 字元串.index('a',1);

如果想比較兩個字元串是否相等:字元串.equeals(字元串);

判斷字元串是否為空:字元串.isEmpty();

獲取字元串的長度:字元串.length();

根據某一個條件,將字元串進行分割:字元串.split("abc");

根據條件取出內容:字元串.substring(開始位置,結束位置);



『拾』 JVM 性能調優方法

JVM性能調優有很多設置,這個參考JVM參數即可.
主要調優的目的:
控制GC的行為.GC是一個後台處理,但是它也是會消耗系統性能的,因此經常會根據系統運行的程序的特性來更改GC行為
控制JVM堆棧大小.一般來說,JVM在內存分配上不需要你修改,(舉例)但是當你的程序新生代對象在某個時間段產生的比較多的時候,就需要控制新生代的堆大小.同時,還要需要控制總的JVM大小避免內存溢出
控制JVM線程的內存分配.如果是多線程程序,產生線程和線程運行所消耗的內存也是可以控制的,需要通過一定時間的觀測後,配置最優結果。