獲取java內存
Ⅰ 如何獲得java對象的內存地址
publicclass對象地址
{
publicstaticvoidmain(String[]args)
{
System.out.println(" ==========如何獲取對象地址?========== ");
init();
}//初始化!
privatestaticvoidinit()
{
//演示:創建對象!
Dogd1=newDog();
Dogd2=newDog("白色");
d1.show();
d2.show();
System.out.println(" 對象內存地址-->>對象所屬類型:"+d1+"<<--這就是對象內存中哈希值16進制的地址");
System.out.println("對象內存地址-->>對象所屬類型:"+d2+"<<--這就是對象內存中哈希值16進制的地址 ");
System.out.println("d1對象所屬類:"+d1.getClass());
System.out.println("d1對象所屬地址十進制:"+d1.hashCode()+"轉成16進制就和上面一樣了 ");
System.out.println("d2對象所屬類:"+d2.getClass());
System.out.println("d2對象所屬地址十進制:"+d2.hashCode()+"轉成16進制就和上面一樣了 ");
}
}
//測試類,小狗!
classDog
{
Stringcolor="黑色";
Dog(){}
Dog(Stringcolor){this.color=color;}
voidshow()
{
System.out.println("這是一個"+color+"的小狗");
}
}
Ⅱ 如何獲得java對象的內存地址
java中不建議直接獲取字元串內存地址,因為java不像c語言,獲取內存地址是C語言的強項,java的弱項。但是java內存地址還是有一個應用場景,就是判斷兩個字元串內存地址是否相等來判斷是否是同一個對象,用雙等號「==」來比較的。參考代碼如下:
public class Test01 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String str1="abc";
String str2=new String("abc");
System.out.println(str1 == str2);//輸出false
}
}
Ⅲ 如何獲取到JAVA對象所在的內存地址
1、首先打開java構造方法代碼。
(3)獲取java內存擴展閱讀
當使用80386時,必須區分以下三種不同的地址:
邏輯地址:機器語言指令仍用這種地址指定一個操作數的地址或一條指令的地址。這種定址方式在Intel的分段結構中表現得尤為具體,它使得MS-DOS或Windows程序員把程序分為若干段。每個邏輯地址都由一個段和偏移量組成。
線性地址:針對32位CPU,線性地址是一個32位的無符號整數,可以表達高達2³² (4GB)的地址。通常用16進製表示線性地址,其取值范圍為0x00000000~0xffffffff。對64位CPU,線性地址是一個64位的無符號整數,可以表達高達2⁶⁴ 。
物理地址:也就是內存單元的實際地址,用於晶元級內存單元定址。物理地址也由32位無符號整數表示。
電腦的內存(尤其是指主存)是由許多「內存地址」所組成的,每個內存地址都有一個「物理地址」,能供CPU(或其他設備)訪問。一般,只有如BIOS、操作系統及部分特定之公用軟體(如內存測試軟體)等系統軟體;
能使用機器碼的運算對象或寄存器對物理地址定址,指示CPU要求內存控制器之類的硬體設備,使用內存匯流排或系統匯流排,亦或分別之控制匯流排、地址匯流排及數據匯流排,運行該程序之命令。
內存控制器的匯流排是由數條並行的線路所組成的,每條線路表示一個比特。匯流排的寬度因此依電腦不同,決定了可定址之存儲單位數量,以及每一單位內的比特數量。
計算機程序使用內存地址來運行機器碼、存儲及截取數據。大多數的應用程序無法得知實際的物理地址,而是使用電腦的內存管理單元及操作系統的內存映射,為「邏輯地址」或虛擬地址定址。
Ⅳ 怎樣查看JAVA內存的大小
首先先說一下JVM內存結構問題,JVM為兩塊:PermanentSapce和HeapSpace,其中
Heap = }。PermantSpace負責保存反射對象,一般不用配置。JVM的Heap區可以通過-X參數來設定。
當一個URL被訪問時,內存申請過程如下:
A. JVM會試圖為相關Java對象在Eden中初始化一塊內存區域
B. 當Eden空間足夠時,內存申請結束。否則到下一步
C. JVM試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收), 釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區
D. Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區
E. 當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級)
F. 完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建內存區域,則出現」out of memory錯誤」
JVM調優建議:
ms/mx:定義YOUNG+OLD段的總尺寸,ms為JVM啟動時YOUNG+OLD的內存大小;mx為最大可佔用的YOUNG+OLD內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
NewSize/MaxNewSize:定義YOUNG段的尺寸,NewSize為JVM啟動時YOUNG的內存大小;MaxNewSize為最大可佔用的YOUNG內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
PermSize/MaxPermSize:定義Perm段的尺寸,PermSize為JVM啟動時Perm的內存大小;MaxPermSize為最大可佔用的Perm內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
SurvivorRatio:設置Survivor空間和Eden空間的比例
內存溢出的可能性
1. OLD段溢出
這種內存溢出是最常見的情況之一,產生的原因可能是:
1) 設置的內存參數過小(ms/mx, NewSize/MaxNewSize)
2) 程序問題
單個程序持續進行消耗內存的處理,如循環幾千次的字元串處理,對字元串處理應建議使用StringBuffer。此時不會報內存溢出錯,卻會使系統持續垃圾收集,無法處理其它請求,相關問題程序可通過Thread Dump獲取(見系統問題診斷一章)單個程序所申請內存過大,有的程序會申請幾十乃至幾百兆內存,此時JVM也會因無法申請到資源而出現內存溢出,對此首先要找到相關功能,然後交予程序員修改,要找到相關程序,必須在Apache日誌中尋找。
當Java對象使用完畢後,其所引用的對象卻沒有銷毀,使得JVM認為他還是活躍的對象而不進行回收,這樣累計佔用了大量內存而無法釋放。由於目前市面上還沒有對系統影響小的內存分析工具,故此時只能和程序員一起定位。
2. Perm段溢出
通常由於Perm段裝載了大量的Servlet類而導致溢出,目前的解決辦法:
1) 將PermSize擴大,一般256M能夠滿足要求
2) 若別無選擇,則只能將servlet的路徑加到CLASSPATH中,但一般不建議這么處理
3. C Heap溢出
系統對C Heap沒有限制,故C Heap發生問題時,Java進程所佔內存會持續增長,直到佔用所有可用系統內存
參數說明:
JVM 堆內存(heap)設置選項
參數格式
說 明
設置新對象生產堆內存(Setting the Newgeneration heap size)
-XX:NewSize
通過這個選項可以設置Java新對象生產堆內存。在通常情況下這個選項的數值為1 024的整數倍並且大於1MB。這個值的取值規則為,一般情況下這個值-XX:NewSize是最大堆內存(maximum heap size)的四分之一。增加這個選項值的大小是為了增大較大數量的短生命周期對象
增加Java新對象生產堆內存相當於增加了處理器的數目。並且可以並行地分配內存,但是請注意內存的垃圾回收卻是不可以並行處理的
設置最大新對象生產堆內存(Setting the maximum New generation heap size)
-XX:MaxNewSize
通過這個選項可以設置最大Java新對象生產堆內存。通常情況下這個選項的數值為1 024的整數倍並且大於1MB
其功用與上面的設置新對象生產堆內存-XX:NewSize相同
設置新對象生產堆內存的比例(Setting New heap size ratios)
-XX:SurvivorRatio
新對象生產區域通常情況下被分為3個子區域:伊甸園,與兩個殘存對象空間,這兩個空間的大小是相同的。通過用-XX:SurvivorRatio=X選項配置伊甸園與殘存對象空間(Eden/survivor)的大小的比例。你可以試著將這個值設置為8,然後監控、觀察垃圾回收的工作情況
設置堆內存池的最大值(Setting maximum heap size)
-Xmx
通過這個選項可以要求系統為堆內存池分配內存空間的最大值。通常情況下這個選項的數值為1 024的整數倍並且大於1 MB
一般情況下這個值(-Xmx)與最小堆內存(minimum heap size –Xms)相同,以降低垃圾回收的頻度
取消垃圾回收
-Xnoclassgc
這個選項用來取消系統對特定類的垃圾回收。它可以防止當這個類的所有引用丟失之後,這個類仍被引用時不會再一次被重新裝載,因此這個選項將增大系統堆內存的空間
設置棧內存的大小
-Xss
這個選項用來控制本地線程棧的大小,當這個選項被設置的較大(>2MB)時將會在很大程度上降低系統的性能。因此在設置這個值時應該格外小心,調整後要注意觀察系統的性能,不斷調整以期達到最優
最後說一句,你的機器的連接數設置也至關重要,連接的關閉最好把時間設置的少些,那些連接非常耗費資源。也是引起內存泄露的主要原因。
Ⅳ 如何獲得java對象的內存地址
在java中內存中的對象地址是可變的,所以獲得的內存地址有可能會變化。要獲得內存地址也只能通過Unsafe的方法來獲得,如下代碼示例:
packagecom.bijian.study;
importjava.lang.reflect.Field;
importsun.misc.Unsafe;
publicclassAddresser{
//實例化Unsafe 類
privatestaticUnsafeunsafe;
static{
try{
//得到field對象
Fieldfield=Unsafe.class.getDeclaredField("theUnsafe");
//設置獲取地址
field.setAccessible(true);
unsafe=(Unsafe)field.get(null);
}catch(Exceptione){
e.printStackTrace();
}
}
publicstaticlongaddressOf(Objecto)throwsException{
Object[]array=newObject[]{o};
longbaseOffset=unsafe.arrayBaseOffset(Object[].class);
intaddressSize=unsafe.addressSize();
longobjectAddress;
switch(addressSize){
case4:
objectAddress=unsafe.getInt(array,baseOffset);
break;
case8:
objectAddress=unsafe.getLong(array,baseOffset);
break;
default:
thrownewError("unsupportedaddresssize:"+addressSize);
}
return(objectAddress);
}
//列印地址的長度
publicstaticvoidmain(String...args)throwsException{
Objectmine="Hithere".toCharArray();
longaddress=addressOf(mine);
System.out.println("Addess:"+address);
//Verifyaddressworks-
printBytes(address,27);
}
//調用此方法得到地址
publicstaticvoidprintBytes(longobjectAddress,intnum){
//循環列印得到的地址。
for(longi=0;i<num;i++){
intcur=unsafe.getByte(objectAddress+i);
System.out.print((char)cur);
}
System.out.println();
}
}
運行結果:
Ⅵ java 如何獲得一個進程的內存使用情況,cpu運行的時間
首先有個基本問題需要了解一下:
這里所說java里獲得一個進程的內存使用情況和cpu運行時間,是指在java內部獲取一個純外部進程的內存與cpu時間呢,還是指在java內部,由java啟動的進程的內存與cpu時間。
如果是第一種情況,那你還需要在java內部再起一個進程,通過執行操作系統的shell命令來查看那個進程的運行狀態。比如那個外部進程的ID為3119,則執行cat /proc/3119/status | grep VmRSS就可以過濾出該進程的物理內存佔用量。
如果是第二種情況,(假定你問的就是這種情況)。
先說內存佔用量:一般說來,你可以使用這兩種方式獲取內存使用情況
方式一:
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage(); //椎內存使用情況
long totalMemorySize = memoryUsage.getInit(); //初始的總內存
long maxMemorySize = memoryUsage.getMax(); //最大可用內存
long usedMemorySize = memoryUsage.getUsed(); //已使用的內存
方式二:
Runtime rt = Runtime.getRuntime();
long totalMemorySize = rt.totalMemory(); //初始的總內存
long maxMemorySiz = t.maxMemory(); //最大可用內存
long freeMemorySize = rt.freeMemory(); //當前可用內存
需要說明的是,這種方式獲取的是整個jvm的內存使用情況,並不是某一個進程的內存使用情況,事實上,在java內部,可以使用Rumtime.getRuntime().exec(${SHELL})來開啟一個外部進程(這里${SHELL}代表一個可操作系統的shell命令)。而運行Java程序整個jvm,對於操作系統而言,也僅僅只是一個進程。也就是說,一個jvm就是一個進程,你通過java程序開啟的進程都是外部進程,java內部目前還提供了一個destroy方法來銷毀該進程,對於該進程的其它信息,都無法直接獲取,這些信息的獲取,顯然需要本地化(Local)的實現。既然標准jdk庫沒有,就不可能再通過平台無關的代碼來實現了。典型的做法就是使用前面第一種情況的方式,再啟一個進程,執行shell命令來獲取。
不過對於cpu使用時間,採用標准java代碼倒是可以拿到。由於java的語法很啰嗦,舉一個較完全的例子需要太多的代碼,我這里就只寫最關鍵的代碼:
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
① long currentCpuTime = threadMXBean.getCurrentThreadCpuTime(); //當前線程的cpu使用時間
long someThreadId = 709817L; //假定有某個線程的ID是709817
② long someThreadCpuTime = threadMXBean.getThreadCpuTime(someThreadId); //獲取ID為someThreadId即709817的線程的cpu時間
基於上面的核心api,你可以把由java啟動的外部進程放到一個單獨的線程中執行,再用代碼②的方式來獲取該進程的cpu使用時間,也可以將外部進程放入到當前線程中執行,用① 的方式來獲得進程的cpu使用時間。