C++?重載運(yùn)算符在HotSpot?VM中的應(yīng)用小結(jié)
C++支持運(yùn)算符重載,對于Java開發(fā)者來說,這個(gè)可能比較陌生一些,因?yàn)镴ava不支持運(yùn)算符重載。運(yùn)算符重載本質(zhì)上來說就是函數(shù)重載。下面介紹一下HotSpot VM中的運(yùn)算符重載。
1、內(nèi)存分配與釋放
在C++中可以通過new運(yùn)算符創(chuàng)建一個(gè)C++的類實(shí)例,這個(gè)操作實(shí)際上上包含了如下3個(gè)步驟:
- 調(diào)用operator new的標(biāo)準(zhǔn)庫函數(shù)。此函數(shù)會分配一塊內(nèi)存空間以便函存儲相應(yīng)類型的實(shí)例。
- 調(diào)用相應(yīng)類的構(gòu)造函數(shù)
- 返回一個(gè)指向該對象的指針
同樣,可以delete運(yùn)算符釋放對應(yīng)的內(nèi)存,實(shí)際執(zhí)行如下2個(gè)步驟:
- 調(diào)用相應(yīng)類的析構(gòu)函數(shù)
- 調(diào)用operator delete標(biāo)準(zhǔn)庫函數(shù)釋放內(nèi)存。
由于C++沒有Java的GC托管技術(shù),所以分配出來的內(nèi)存時(shí)刻要惦記著釋放,這是一件非常不容易的事情。通常的做法是,內(nèi)存申請和釋放集中到一個(gè)地方管理,所以才會有Metaspace或Arena這些相對復(fù)雜一些的內(nèi)存管理機(jī)制。
有了我們自己設(shè)計(jì)的內(nèi)存管理機(jī)制后,就可以重載new運(yùn)算符,讓實(shí)例從特定的內(nèi)存空間中申請和釋放內(nèi)存了,例如HotSpot VM在Klass類中重載了new運(yùn)算符:
void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw() {
// 在元數(shù)據(jù)區(qū)分配內(nèi)存空間
void* x = Metaspace::allocate(
loader_data,
word_size,
false, /*read_only*/
MetaspaceObj::ClassType,
CHECK_NULL
);
return x;
}在使用new關(guān)鍵字創(chuàng)建Klass或子類的實(shí)例時(shí),都會調(diào)用Metaspace::allocate()函數(shù)從元數(shù)據(jù)區(qū)分配內(nèi)存;在Klass類中,我們沒有看到重載delete運(yùn)算符,因?yàn)閯h除一個(gè)類并沒有那么簡單,需要借助GC來完成。元數(shù)據(jù)區(qū)具體管理內(nèi)存的辦法,以及分配和釋放的邏輯可參看《深入剖析Java虛擬機(jī):源碼剖析與實(shí)例詳解》中的8.2節(jié)。
在HotSpot VM中重載new和delete運(yùn)算符的地方非常多,不過oop并不是這樣做的,這應(yīng)該是考慮到它相對復(fù)雜的內(nèi)存分配邏輯和初始化過程吧。
2、句柄
關(guān)于句柄,可以參考 http://m.dhdzp.com/article/141842.htm 。句柄要間接操作實(shí)例,讓GC能夠集中掃描到棧中引用到的Java對象。
句柄的相關(guān)定義如下:
class Handle {
private:
oop *_handle; // oop的類型為oopDesc*
protected:
oop obj() const {
return _handle == NULL ? (oop) NULL : *_handle;
}
oop non_null_obj() const {
return *_handle;
}
public:
// 重載了()、->和==運(yùn)算符
oop operator()() const { return obj(); }
oop operator->() const { return non_null_obj(); }
bool operator==(oop o) const { return obj() == o; }
bool operator==(const Handle &h) const { return obj() == h.obj(); }
};句柄中重載了()、->和==運(yùn)算符,我們可以這樣操作:
oop obj1 = ...; // 將對象封裝為句柄 Handle h1(obj1); // 獲取被封裝的對象,會調(diào)用到operator()()函數(shù),這個(gè)函數(shù)返回*_handle oop obj2 = h1(); // 直接調(diào)用oop中定義的相關(guān)函數(shù),會調(diào)用到operator->()函數(shù), // 在這個(gè)函數(shù)中獲取_handle值后調(diào)用_handle->print()函數(shù) h1->print();
這大大簡化了相關(guān)操作的簡潔性,操作句柄就感覺和操作oop是一樣的效果
到此這篇關(guān)于C++ 重載運(yùn)算符在HotSpot VM中的應(yīng)用的文章就介紹到這了,更多相關(guān)C++ 重載運(yùn)算符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解C語言中動(dòng)態(tài)內(nèi)存管理及柔性數(shù)組的使用
這篇文章主要為大家詳細(xì)介紹一下C語言中動(dòng)態(tài)內(nèi)存管理以及柔性數(shù)組的使用方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定的幫助,需要的可以參考一下2022-07-07
C++中vector的模擬實(shí)現(xiàn)實(shí)例詳解
vector是表示可變大小數(shù)組的序列容器,它也采用連續(xù)存儲空間來存儲元素,因此可以采用下標(biāo)對vector的元素進(jìn)行訪問,這篇文章主要給大家介紹了關(guān)于C++中vector模擬實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2021-11-11

