1. 程式人生 > >對象的內存布局

對象的內存布局

next clu pos return bin 部分 PE warning literal

對象在內存中存儲的布局分為:
對象頭(Header)、實例數據(Instance Data)和對齊填充(Padding)
1. 對象頭包括兩部分信息,第一部分用於存儲對象自身的運行時數據,如哈希碼(HashCode)、GC分代年齡、鎖狀態標誌、線程持有的鎖、
偏向線程ID、偏向時間戳等
對象頭信息是與對象自身定義的數據無關的額外存儲成本,考慮到虛擬機的空間效率,Mark Word被設計成一個非固定的數據結構
以便在 極小的空間內存儲盡量多的信息,它會根據對象的狀態復用自己的存儲空間。例如:在32位的HotSpot虛擬機中,如果對象處於未
被鎖定的狀態下,那麽Mark Word的32bit空間中的25bit用於存儲對象哈希碼,4bit用於存儲對象分代年齡,2bit用於存儲鎖標誌位,
1bit固定為0.
其他狀態還有:輕量級鎖定、重量級鎖定、GC標記、可偏向
對象頭的另外一部分是類型指針,即對象指向他的類元素數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例。
2. 實例數據部分是對象真正存儲的有效信息,也是在程序代碼中所定義的各自類型的字段內容。無論是從父類繼承下來的,還是在
子類中定義的,都需要記錄下來。這部分存儲順序會受到虛擬機分配策略參數(FieldsAllocationStyle)和字段在Java源碼中定義
順序的影響。Hotspot虛擬機默認的分配策略為longs/doubles、ints、shorts/chars、bytes/booleans、opps(Ordinary Object Pointers)
從分配策略可以看出,相同寬度的字段總是被分配到一起。
在滿足在咱這個前提條件下,在父類中定義的變量會出現在子類之前。
3. 第三部對齊填充並不是必然存在的,也沒有特別的含義,僅僅起著占位符的作用。由於HotSpot VM的自動內存管理系統要求對象起始地址
必須是8字節的整數倍,換句話說,就是對象的大小必須是8字節的整數倍。而且對象部分正好是8字節的倍數(1倍或者2倍),
因此,當對象實例數據部分沒有對齊時,就需要通過對齊填充來補全。

編譯hotspot進展

1./usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lgcc_s

2. invalid suffix on literal; C++11 requires a space between literal and string macro [-Werror=literal-suffix]
gclog_or_tty->print("TLAB: %s thread: "INTPTR_FORMAT" [id: %2d]"
無效的後綴文字;c++ 11需要在文字和字符串宏之間有一個空格[-Werror= literalsuffix]
修改為gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
3. error: "__LEAF" redefined [-Werror]
#define __LEAF(result_type, header) \
修改為:
429 #ifdef __LEAF
430 #undef __LEAF
431 #define __LEAF(result_type, header) \
432 TRACE_CALL(result_type, header) \
433 debug_only(NoHandleMark __hm;) \
434 /* begin of body */
435 #endif
4. error: ‘int readdir_r(DIR*, dirent*, dirent**)‘ is deprecated [-Werror=deprecated-declarations]


if((status = ::readdir_r(dirp, dbuf, &p)) != 0) 未解決
vi /usr/include/dirent.h
#pragma disable(warning:4244)
For existing releases (7,8, 9), I think the right thing is to just disable the deprecation warning
錯誤:‘int readdir_r(DIR*, dirent*, dirent**)‘被棄用[-Werror=不支持聲明]
/* Reentrant version of `readdir‘. Return in RESULT a pointer to the
next entry.
This function is a possible cancellation point and therefore not
marked with __THROW. */
# ifndef __USE_FILE_OFFSET64
extern int readdir_r (DIR *__restrict __dirp,
struct dirent *__restrict __entry,
struct dirent **__restrict __result)
__nonnull ((1, 2, 3)) __attribute_deprecated__;
# else
# ifdef __REDIRECT
extern int __REDIRECT (readdir_r,
(DIR *__restrict __dirp,
struct dirent *__restrict __entry,
struct dirent **__restrict __result),
readdir64_r)
__nonnull ((1, 2, 3)) __attribute_deprecated__;
# else
# define readdir_r readdir64_r
# endif
# endif

對象的內存布局