1. 程式人生 > >java中的堆非堆記憶體

java中的堆非堆記憶體

堆(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檔案的設定規則:

引數形如“項值”這種形式,中間有空格的需要換行書寫,如果值中有空格的需要用雙引號包括起來。比如我們使用-vmC:\Java\jre1.6.0\bin\javaw.exe引數設定虛擬機器,在eclipse.ini檔案中要寫成這樣:

  1. -vm  
  2. C:\Java\jre1.6.0\bin\javaw.exe  

按照上面所說的,最後引數在eclipse.ini中可以寫成這個樣子:

  1. -vmargs  
  2. -Xms128M  
  3. -Xmx512M  
  4. -XX:PermSize
    =64M
  5. -XX:MaxPermSize=128M

實際執行的結果可以通過Eclipse中“Help”-“AboutEclipseSDK”窗口裡面的“ConfigurationDetails”按鈕進行檢視。

另外需要說明的是,Eclipse壓縮包中自帶的eclipse.ini檔案內容是這樣的:

  1. -showsplash  
  2. org.eclipse.platform  
  3. --launcher.XXMaxPermSize  
  4. 256m  
  5. -vmargs  
  6. -Xms40m  
  7. -Xmx256m  

其中–launcher.XXMaxPermSize(注意最前面是兩個連線線)跟-XX:MaxPermSize引數的含義基本是一樣的,我覺得 唯一的區別就是前者是eclipse.exe啟動的時候設定的引數,而後者是eclipse所使用的JVM中的引數。其實二者設定一個就可以了,所以這裡 可以把–launcher.XXMaxPermSize和下一行使用#註釋掉。

3.其他的啟動引數。如果你有一個雙核的CPU,也許可以嘗試這個引數:

  1. -XX:+UseParallelGC  

讓GC可以更快的執行。(只是JDK5裡對GC新增加的引數)

相關推薦

java記憶體

堆(Heap)和非堆(Non-heap)記憶體 按照官方的說法:“Java 虛擬機器具有一個堆,堆是執行時資料區域,所有類例項和陣列的記憶體均從此處分配。堆是在 Java 虛擬機器啟動時建立的。”“在JVM中堆之外的記憶體稱為非堆記憶體(Non-heap memory)”。

Java虛擬機器--記憶體的引數配置(五)

方法區配置 JDK1.6 , JDK1.7配置永久區大小: -XX:PermSize:初始的永久區大小;-XX:MaxPermSize:最大永久區; JDK1.8使用元資料區替代永久區: 預設情

Java棧和的區別

分配內存 基本 變量 類型 名稱 垃圾回收器 函數 一個數 棧內存 在函數中定義的一些基本類型的變量和對象的引用變量都在函數的棧內存中分配。當在一段代碼塊定義一個變量時,Java就在棧中為這個變量分配內存空間,當超過變量的作用域後,Java會自動釋放掉為該變量

Java的基礎----與棧的介紹、區別

堆和棧都是Java中常用的儲存結構,都是記憶體中存放資料的地方。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我是可愛的分割線~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 堆:

Java棧和講解

之前對JVM中堆記憶體和棧記憶體都是一直半解,今天有空就好好整理一下,用做學習筆記。    包括Java程式在內,任何程式在執行時都是要開闢記憶體空間的。JVM執行時在記憶體中開闢一片記憶體區域,啟動時在自己的記憶體區域中進行更細緻的劃分,因為虛擬機器中每一片記憶體處理的方式都

Java的陣列和記憶體分配

理解陣列 概念:陣列是儲存同一種資料型別多個元素的集合。也可以看成是一個容器。 陣列既可以儲存基本資料型別,也可以儲存引用資料型別,只要所有的陣列元素具有相同的資料型別即可 定義陣列的方法: ①:type[] arrayName;(推薦使用這種方式) ②:ty

javadouble型別的記憶體表示

轉自[http://bbs.csdn.net/topics/260050279] 浮點數儲存的位元組格式如下: 地址 +0 +1 +2 +3 內容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM 這裡 S 代表符號位,1是負,0是正 E 偏移1

Java建立物件的記憶體

  所有人都知道面向物件思想,Java中的物件的建立在記憶體中是如何建立的,傳智播客的視訊看了一遍,把一些講解的比較清晰的內容記錄下來,方便記憶的更加深刻,Java中建立物件的過程,首先要理解JVM中棧、堆、方法區的空間,以及在這三個空間內,虛擬機器都進行什麼操作,這樣就會理解起來容易一些,其實Ja

java物件可以存在記憶體哪些地方

注意:以下都是個人理解。如有不同之處,望提出(-_-)。 java中識別符號對應的值可以改變的叫做變數,不可以改變的叫做常量。如: //識別符號a的值可以改變,叫做變數 int a=3; a=4; //識別符號b的值不可以改變,叫做常量 final int b=3;

Java內部類的記憶體洩露問題

package com.example.temptemp; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.Text

javaArrayList之clear記憶體回收

右邊為呼叫clear後記憶體情況 現將list.clear改為 list=null,再看看執行情況 賦值NULL後不僅列表中的物件變成了垃圾,為列表分配的空間也會回收 clear()只是清除了物件的引用,使那些物件成為垃圾

java 三種常見記憶體溢位錯誤的處理方法

相信有一定Java開發經驗的人或多或少都會遇到OutOfMemoryError的問題,這個問題曾困擾了我很長時間,隨著解決各類問題經驗的積累以及對問題根源的探索,終於有了一個比較深入的認識。 在解決java記憶體溢位問題之前,需要對jvm(java虛擬機器)的

關於java靜態程式碼塊和靜態程式碼塊

非靜態程式碼塊如: { System.out.println("2"); }以上程式碼塊就是非靜態的程式碼塊,請注意這裡的方法名、作用域、返回值、引數一概沒有,非靜態程式碼塊會在每次類被呼叫或者被例項化時就會被執行。 靜態程式碼塊如: static { Syst

Java建立物件在記憶體做了哪些事情?

Student s = new Student();//做了哪些事情?A:把Student.class檔案載入到記憶體B:在棧記憶體給s變數開闢一個空間C:在堆記憶體為學生物件申請一個空間D:給成員變數進行預設初始化E:通過構造方法給成員變數進行顯示初始化F:通過構造方法給成

java三種常見記憶體溢位錯誤的處理方法

相信有一定java開發經驗的人或多或少都會遇到OutOfMemoryError的問題,這個問題曾困擾了我很長時間,隨著解決各類問題經驗的積累以及對問題根源的探索,終於有了一個比較深入的認識。 在解決java記憶體溢位問題之前,需要對jvm(java虛擬機器

Java記憶體分配以及棧和的區別

Java中的記憶體分配以及棧和堆的區別 (1)棧: 存放的是區域性變數 區域性變數:在方法定義中或者方法宣告上的變數都是區域性變數。 (2)堆: 存放的是所有new出來的東西 特點: a: 每一個new出來的東西都會為其分配一個地制值。 b: 每

Java記憶體和棧記憶體

Java中的堆記憶體和棧記憶體 本文主要討論作者對於Java記憶體中堆疊的理解. Oralce官方對於棧(stack)的解釋: Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at

#一分鐘讓你瞭解Java記憶體,棧記憶體

java堆疊 java面試過程中經常會被問到關於堆疊的問題,這裡我稍微總結一下,供大家參考一下。 java的記憶體分為堆記憶體和棧記憶體 棧記憶體是指程式進入一個方法時,會為這個方法單獨分配一塊私屬儲存空間,用於儲存這個方法內部的區域性變數,當這個方法結束時,分配給這個方法的棧會釋

java記憶體和棧記憶體的分配

java中堆記憶體和棧記憶體的分配 class Person{ private String name; private int age; public Person()//無參的構造方法 { System.out.println("***