æåããå§ããŸãããã ã¬ããŒãžã³ã¬ã¯ã¿ãŒãšã¯äœã§ããïŒ
Gargabe CollectorïŒGCïŒã¯ããªãœãŒã¹ïŒéåžžã¯ããŒãã«å²ãåœãŠãããRAMïŒã管çããããã®æ¹æ³ã§ãã äžçªäžã®è¡ã¯ç°¡åã§ã-ããã°ã©ããŒã¯ã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ã¡ã¢ãªã®äžéšãå²ãåœãŠãããã«èŠæ±ããŸããã圌ã¯äžèŠã«ãªã解æŸã§ããææãæ¢ã«æ±ºå®ããŠããŸãã ããã«ãããã»ãšãã©ã®ã¡ã¢ãªãªãŒã¯ã®åé¡ã解決ãããŸãããã»ã°ã¡ã³ããŒã·ã§ã³ãšã©ãŒãèªåŒµããŠèªåŒµããããšã¯äžå¯èœã«ãªããŸãã ãªããŠæ®å¿µã
ã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ã¯ãä¿å®çãšã³ããŒã®2çš®é¡ããããŸãã
æåã®ã¿ã€ãã®ãããªãã®ãææ°ã®æšæºã«å®è£ ãããŠããŸãã shared_ptrã¡ã«ããºã ã¯ãnewããã³deleteæŒç®åã®æ瀺çãªäœ¿çšãæé€ããŸãã ãªããžã§ã¯ããæããªã³ã¯ãã«ãŠã³ããããããã®æ°ããŒãã«ãªããšãããåãé€ããŸãã ãã®ã¢ãããŒãã®åé¡ã¯ãå€ãã®å°ããªãªããžã§ã¯ããåã寿åœã§ã¯ãªãçã寿åœã§äœæãããå Žåã«çºçããŸãã ãã®çµæãããŒãã¯æå¹ãªãªããžã§ã¯ãã®è¡ãŸã¿ãã®æ··ä¹±ã«å€ãããæ°åãã€ãã®ç©ºãã¡ã¢ãªã®æçã«ãªããŸãã ãã®ãããæ°ãããªããžã§ã¯ãã®äœæã¯æ°žé ã«ãããå§ãããã€ãã£ãã³ãŒãã¯Pythonãvyæãå§ããŸãã
ãã®åé¡ã解決ããããã«-ããŒãã®æçå-ã³ã¬ã¯ã¿ãŒã®2çªç®ã®ã¿ã€ããçºæãããŸãã-ã³ããŒããŸãã åœåã®éã圌ã®ãã¿åŠçæŠç¥ã¯çèã§ãã éå°ã«ãªã£ãå Žåã圌ã¯æ¬¡ã®ããšãè¡ããŸãã
1.å¿ èŠãªãã¹ãŠã®ããŒã¿ãå¥ã®ã¡ã¢ãªé åã«ã³ããŒããŸãã
2.ãã¹ãŠã®ãã€ã³ã¿ãŒãé¢é£ãããã®ã«å€æŽããŸãã
3.䜿çšãããªããªã£ããã¹ãŠã®ã¡ã¢ãªã解æŸããŸãã
ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã¢ã«ãŽãªãºã ããC ++ã®ãã¢ãã«ããGCã©ã€ãã©ãªãã©ã®ããã«æ©èœãããã«ã€ããŠã¯è©³ããèŠãŠããªãããšãããã«æããã«ããŸãã ãããããããã§èª¬æããã¢ã«ãŽãªãºã ã«ã¯ååãããããååããããŸãããããã§ã¯ãœãŒã¹ãžã®åç §ãªãã§è¡ããŸãã
ããã°ã©ã ããŸã å¿ èŠãšãããªããžã§ã¯ãã決å®ããããã«ãã¡ã¢ãªãéåžžã®ã°ã©ããšèŠãªãããšãææ¡ããŸãã 次ã«ãã¬ããŒãžã³ã¬ã¯ã·ã§ã³åŸã®ããªãã³ã°ããªããžã§ã¯ãã¯ããã€ã³ã¿ãŒã®ãã§ãŒã³ãä»ããŠå°éå¯èœãªãªããžã§ã¯ããšèŠãªãããŸãã ããã«ããçåãçããŸãã ãŸããããã°ã©ããŒãäœæãèŠæ±ããå¯èœæ§ã®ãããªããžã§ã¯ãã«ã€ããŠã¯ãã©ãã«ãã€ã³ã¿ãŒãããããå€å¥ããŸãã æåã®æ¹æ³ã¯ããªããžã§ã¯ãã®åã¯ã©ã¹ã«ãã³ãã¬ãŒãããžãã¯ã䜿çšããŠç¬èªã®ã¢ãã±ãŒã¿ãŒãäœæããããšã§ãã å€ãã®çç±ã§æãããã¢ã€ãã¢ã 2ã€ç®ã¯ãGCãæ©èœããããã«å¿ èŠãªãã¹ãŠã®æ å ±ãåãªããžã§ã¯ãã®ããããŒã«æžã蟌ãããšã§ãïŒããããã®å®è£ ã¯ä»®æ³é¢æ°ãæã€ã¯ã©ã¹ã«ã¯é©ããŠããŸãããå¿ èŠã«å¿ããŠããã€ãã®ã¢ã€ãã¢ããããŸãïŒã
ããããŒã¯ããŸããŸãªæ¹æ³ã§ã䜿çšã§ããŸãã ç§ã®ãã®ã¯ãæãç°¡åãªãã®ã§ãïŒå®è£ ã®ããã§ããã䜿çšããªãããïŒã ãŸããã¬ããŒãžã³ã¬ã¯ã¿ãŒãä»ããŠäœæãããäºå®ã®ãã¹ãŠã®ãªããžã§ã¯ãã¯ãå®çŸ©ã®æåã«æ¬¡ã®æ§é ãæã€å¿ èŠããããŸãã
enum { STRUCT_SZ = 0, REF_COUNT = 1 }; struct gcHeader { union { int gcData[2]; gcHeader* post_gcAddress; }; };
第äºã«ãããããŒã®çŽåŸã§ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ãé©çšããããã¹ãŠã®ãã€ã³ã¿ãŒã移åããå¿ èŠããããŸãã ãããã£ãŠããããã®çªå·ã¯gcData [REF_COUNT]ã«ä¿åãããŸãã ããã¯ãç§ã®å®è£ ã課ãå¶éã®1ã€ã§ãã GcData [STRUCT_SZ]ã¯ãæ§é äœã®ãµã€ãºããã€ãåäœã§ä¿åããŸãã ãã€ã³ã¿ãŒã®ç®çã¯åŸã§æããã«ããŸãã 䟿å©ãªã®ã¯ãæ§é ã®ãµã€ãºããã€ã³ã¿ãŒã®ãµã€ãºã«çããããšã§ãïŒçŸåšã¯2014幎ã§ãïŒïŒã
çŽ æŽããããä»ç§ãã¡ã®èšæ¶ãåé¿ããããšãã§ããŸãã åé¡ã¯ãã©ãã«ç§»åãããã§ãã ãã€ã§ã絶察ã«ã¢ã¯ã»ã¹ã§ããã¡ã¢ãªã®å¯äžã®é åã¯ã¹ã¿ãã¯ã§ãã åé¡ã¯ãæ§é äœã®ãã€ã³ã¿ãŒã®å Žåãšåãã§ã-倧éã®ãã€ããGCãªããžã§ã¯ããæããŠããã®ãããããŸããã ãããã£ãŠããã®ãããªåãã€ã³ã¿ãŒã®å Žæã¯æ瀺çã«èšè¿°ããå¿ èŠããããŸãã
vector<gcHeader**> referencesStack; template <class T> class stackRef { public: T* ref; stackRef(){ ref = nullptr; referencesStack.push_back(reinterpret_cast<gcHeader**>(&ref)); } ~stackRef(){ referencesStack.pop_back(); } };
stackRefã¯ã©ã¹ã¯åçŽã«æ©èœããŸãã åæåæã«ãã¢ãã¬ã¹ããªã³ã¯ã¹ã¿ãã¯ã«è¿œå ããã ãã§ãã ãããã£ãŠããã¹ãã©ã¯ã¿ã¯åãã¹ã¿ãã¯ããç¡é¢ä¿ãªã¢ãã¬ã¹ãåé€ããŸãã ãã¹ãã©ã¯ã¿ã䜿çšããåŒã³åºããšã³ã³ã¹ãã©ã¯ã¿ã®ã¹ã¿ãã¯ã¯åæããããããç°åžžã¯çºçããŸããã
ã¯ã©ã¹ã§ã¯ãå€ãã®æŒç®åãåå®çŸ©ããå¿ èŠããããŸã-åç §è§£é€ãå²ãåœãŠãªã©ããã ããBoost Foundationã®æ åœè ããé£çµ¡ãæ¥ãŠããã«ãããè¡ãã®ã¯çã«ããªã£ãŠããŸãã
æ¯ææ§é ã¯æºåãã§ããŠããŸãã ã¡ã¢ãªã®å²ãåœãŠã«ç§»åã§ããŸãã
ãã®ãªãœãŒã¹ç®¡çæ¹æ³ã®åªããæ©èœã¯ããŸãã«ãªãœãŒã¹ã®å²ãåœãŠæ¹æ³ã§ãã åé€ãããã³ã«ãæšæºC ++ã¢ãã±ãŒã¿ãŒã¯ç©ºããããã¯ã®ãªã¹ããæŽæ°ããæ°ãããããã¯ã®äžã§é©åãªãããã¯ãèŠã€ããããã2ã€ã®å°ããªãããã¯ã«åå²ãããã®åŸãçŸä»£ã®ã¢ãã±ãŒã¿ãŒãè¡ãããšãè¡ããŸãã ã¬ããŒãžã³ã¬ã¯ã¿ãŒã®å Žåãåé€æäœã¯åçŽã«å¿ èŠãªãããããã¹ãŠã®å æã¡ã¢ãªã¯1ã€ã®åºäœãããã¯ã«æ ŒçŽãããŸãã æ°ãããªããžã§ã¯ããäœæããã«ã¯ããã®ãããã¯ã®ãµã€ãºã倧ãããããã€ãŸã1ã€ã®ãã€ã³ã¿ãŒã移åããã ãã§ãã OïŒ1ïŒã§å®è¡ãããç°¡åãªæäœã å®éãäžèŠãªã¡ã¢ãªãåå©çšã§ããå Žåã«å€§éã®ã¢ã»ã³ããªãåŒã³åºããŸãããä»ã¯ããã§åæ¢ã§ããŸãã
ã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ãã£ãŠå¶åŸ¡ãããã¡ã¢ãªã4ãããã€ãã®æçã«åå²ãããããããªã¹ãã«ãªã³ã¯ããŸãã å®éã4ãããã€ã匷ã§ãããããã¯ç§ã®æ thisã®åé¡ã§ãã
const int CHUNK_SIZE = 4096; const int OVERDRAFT = 128; const int ACTUAL_SIZE = CHUNK_SIZE + OVERDRAFT; // 15 , - . struct gcChunk { gcChunk* next; char data[ACTUAL_SIZE];// . }; gcChunk* firstChunk; gcChunk* currentChunk; int chunkCount; int currentOffset;
firstChunkã¯ãªã¹ãã®å é ãcurrentChunkã¯æåŸã«äœæãããã¡ã¢ãªãããã¯ã§ãã urrentOffset-currentChunkã«é¢é£ãã空ãã¡ã¢ãªã»ã°ã¡ã³ãã®éå§ã
gcHeader* gcRawAlloc(int size, int refCount){ if (size > CHUNK_SIZE)// proof of concept, return nullptr; if (currentOffset + size > CHUNK_SIZE){ // list<gcChunk> STL, , . ++chunkCount; currentChunk->next = new gcChunk(); currentChunk = currentChunk->next; currentChunk->next = nullptr; currentOffset = 0; } gcHeader* new_obj = reinterpret_cast<gcHeader*>(&(currentChunk->data[currentOffset])); new_obj->gcData[STRUCT_SZ] = size; new_obj->gcData[REF_COUNT] = (refCount << 1)| 1; currentOffset += size; if (currentOffset % 4)// 4 . , , .. . currentOffset += 4 - currentOffset % 4; return new_obj;// , , â . }
ãã§ã«å€ãã®æçœã§ãªãç¹ããããŸãã 12è¡ç®ãåæããŸãããã
ãã®æ®µéã§ã¯ãæ°ãããªããžã§ã¯ããã©ã®ã¿ã€ãã§ããããèããªãæ¹ã䟿å©ã§ãã 圌ãgcHeaderãæã£ãŠããããšã¯ç¢ºãã§ããããã§ååã§ãã
æ°ãããªããžã§ã¯ãã«ã¡ã¢ãªãå²ãåœãŠããããã®ã¿ã€ãã«ãåæåããå¿ èŠããããŸãã ç¥ç§çãªå²ãåœãŠãæå³ãããã®
temp->gcData[REF_COUNT] = (refCount << 1)| 1;
ïŒ
ãããè¡ãã«ã¯ãããããŒã®å®çŸ©ãããäžåºŠèŠãŠãã ããã
struct gcHeader { union { int gcData[2]; gcHeader* post_gcAddress; }; };
unionããŒã¯ãŒãã¯ãgcDataé åãšpost_gcAddressãã€ã³ã¿ãŒã®äž¡æ¹ãåãã¢ãã¬ã¹ã«ããããšãæå³ããŸãã ããã¯ã¡ã¢ãªãç¯çŽããã®ã«åœ¹ç«ã¡ãŸãããåé¡ã¯ãC ++ãunionã®ããŒã¿ãæåŸã«ã©ã®ããã«äœ¿çšããããïŒé åãŸãã¯åç §ãšããŠïŒãèŠããŠããªãããšã§ãã ããŒã¿ã®ã¢ã©ã€ã¡ã³ãã®å¿ èŠæ§ãªã©ãããã»ããµã¢ãŒããã¯ãã£ã®æ©èœã圹ç«ã¡ãŸãã
ã€ãŸãã1ãã€ãããé·ãå€æ°ã¯ããã€ãåäœã®ãã·ã³ã¯ãŒãã®åæ°ã®ã¢ãã¬ã¹ã«é 眮ããå¿ èŠããããŸãã ææ°ã®ããã»ããµã§ã®ã¢ã©ã€ã¡ã³ãéåã¯ãããã°ã©ã ã®é床ãå€§å¹ ã«äœäžãããäžè¬çã«å€ãARMã¯ãã®ãããªç¶æ ã§ã®åäœãæåŠããŸãã ãã®çµæãããã°ã©ãã®è£éã§ããã€ã³ã¿ã®æäžäœ2ããããŸãã¯3ããããèªç±ã«äœ¿çšã§ããŸãã ããšãã°ãèµ€é»æšãå®è£ ããå ŽåãããŒã«å€æ°ã®ä»£ããã«æåŸã®ãããããã䜿çšãããŸãã
ãããåãã§ãã æäžäœãããã1ã®å Žåããããã®8ãã€ãã«ã¯2ã€ã®æŽæ°ã®é åãä¿èšŒãããŸãã ããšãã°ãããå°ããããã䜿çšããŠãã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ãããã¯ããªã¢ãŒãã£ãã¯ãªããžã§ã¯ããžã®åç §ã§ãããvtableãã€ã³ã¿ãŒããããäžæžãããªãã§ãã ããããšç€ºãããšãã§ããŸãã
ããŠãã¢ãã±ãŒã¿ãŒã䜿çšããŠãããã»ã©èŠçãçããªãããã«ãé¢æ°ã®å°ããªã©ãããŒã§ãã
template <class T> T* gcAlloc(){ return reinterpret_cast<T*>(gcRawAlloc(sizeof(T), T::refCount)); }
ããã§ãã³ã³ã¹ãã©ã¯ã¿ãŒãæã€ãªããžã§ã¯ããæ£ããåæåãããããã«ãemplace newãé
眮ããå¿
èŠããããŸãã ã芧ã®ãšãããäœæãããªããžã§ã¯ãã®ã¯ã©ã¹ã«ã¯ãéçå®æ°refCountãå¿
èŠã§ãã å€éšããªããã»ããµã䜿çšããŠèªåçã«èšç®ã§ããŸãã ããã§ãªããã°ãããã«ç§ã®è¶³ãæã€å°ãªããšã3ã€ã®æ¹æ³ããããŸãã
ãã®é¢æ°ã䜿çšããåã«ãããŒããåæåããå¿ èŠããããŸãã
void gcInit(){ firstChunk = currentChunk = new gcChunk; firstChunk->next = nullptr; currentOffset = 0; chunkCount = 1; }
ã¬ããŒãžã³ã¬ã¯ã·ã§ã³èªäœã®å®è£ ãèŠãŠã¿ãŸãããã
æåã®é¢æ°gcCollectã¯ãå€ããªã¹ããžã®ãã€ã³ã¿ãŒãä¿åããããšãå¿ããã«ãäžããéå§ããå¿ èŠããããŸãã ãããã®è¡ã¯ãåæåãã»ãŒç¹°ãè¿ããŸãã
void gcCollect(){ //execvp("rm", "cppgc.cpp");// . gcChunk* newFirstChunk = currentChunk = new gcChunk; currentChunk->next = nullptr; currentOffset = 0; chunkCount = 1;
次ã«ãã¹ã¿ãã¯ã«æ ŒçŽãããŠããåãã€ã³ã¿ãŒã䜿çšããŠã¢ã»ã³ããªããã»ã¹ãéå§ããŸãã
for (auto i = referencesStack.begin();i != referencesStack.end(); ++i ) gcMove(*i);
ãããŠä»ãäžèŠãªã¡ã¢ãªã解æŸããŠãã ããã
// , , gcChunk iter = firstChunk; firstChunk = newFirstChunk; while (iter != nullptr){ gcChunk* t = iter->next; delete[] iter; iter = t; } }
deleteã¯å€§ããªã¡ã¢ãªãããã¯ã«å¯ŸããŠã®ã¿åŒã³åºãããããšã«æ³šæããŠãã ããã ãããã£ãŠãã¬ããŒãžã³ã¬ã¯ã¿ãŒã®ãªããžã§ã¯ããã¹ãã©ã¯ã¿ãŒã¯åŒã³åºãããŸããã ããã¯ããã¹ãã©ã¯ã¿ãã¡ã¢ãªã解æŸããã ãã®ã¯ã©ã¹ã§ã¯åé¡ã«ãªããŸããããããšãã°ãæ¥ç¶ãšãã¡ã€ã«èšè¿°åãèªåçã«éããæ¹æ³ã¯ãããŸããã ããã«ã¯MarkïŒSweepã¢ã«ãŽãªãºã ã圹ç«ã¡ãŸãããããããèšè¿°ããã®ã¯ã¯ããã«å°é£ã§ãã
æåŸã®ã¿ããã¯gcMoveé¢æ°ã§ãã
bool isPointer(gcHeader a){ return (a.gcData[REF_COUNT] & 1) == 0; } void gcMove(gcHeader** current){ if (*current == nullptr) return; if (isPointer(**current)){// . , . (*current) = (*current)->post_gcAddress; return; } gcHeader* new_obj = gcRawAlloc((*current)->gcData[STRUCT_SZ], (*current)->gcData[REF_COUNT]); memcpy(new_obj, (*current), sizeof(char) * (*current)->gcData[STRUCT_SZ]); gcHeader** iterator = reinterpret_cast<gcHeader**>(new_obj) + 1; (*current)->post_gcAddress = new_obj; (*current) = new_obj; int refCount = new_obj->gcData[REF_COUNT] >> 1; for (int i = 0; i < refCount; ++i, ++iterator) gcMove(iterator); }
é¢æ°ãçãäžããåæããŸãããã ãªã³ã¯ããªãã€ã¬ã¯ãããæ©èœãå¿ èŠãªã®ã§ãããŒã¿ãžã®ãã€ã³ã¿ãŒãžã®ãã€ã³ã¿ãŒãé¢æ°ã«æž¡ãããŸãã
GCã¯ãå¿ èŠãªéã®ã¡ã¢ãªãæ°ããããŒãå ã®ãªããžã§ã¯ãã«å²ãåœãŠïŒããããŒããã©ãã ãã®éãç¥ã£ãŠãããïŒãå€ãã€ã³ã«ããŒã·ã§ã³ã®ãã¹ãŠã®ããŒã¿ãæ°ãããã®ã«ã³ããŒããŸãã 次ã«ããªããžã§ã¯ãã®æ°ããã¢ãã¬ã¹ãå€ãããããŒã«æžã蟌ã¿ãŸãã çŸåšãè€æ°ã®åç §ããªããžã§ã¯ããæããŠããå Žåãã¢ã«ãŽãªãºã ã¯ãªããžã§ã¯ãããã§ã«1åïŒæäžäœããããä¿èšŒã0ïŒç§»åããããšãå€å¥ã§ãããã®åŸåã³ã³ããŒããããšã¯ãããŸããã å€ããã€ã³ã¿ãŒããªããžã§ã¯ãã®æ°ããã³ããŒã«ãªãã€ã¬ã¯ãããããã«æ®ããŸãã
次ã«ããªããžã§ã¯ãèªäœã®ãã€ã³ã¿ãŒãåŠçããå¿ èŠããããŸãã ããªãã圌ããšåãããšãããå¿ èŠããããŸãã è¡
gcHeader** iterator = reinterpret_cast<gcHeader**>(temp) + 1;
æ§é å ã®æåã®ãªã³ã¯ãžã®ãã€ã³ã¿ãååŸããŸãïŒããããã°ïŒã sizeofïŒgcHeaderïŒ== sizeofïŒvoid *ïŒã§ããããšãå¿ããªãã§ãã ããã ãã以å€ã®å Žåã¯ãããã«æ°è¡ããããŸãã
次ã«ãã¹ãããšã¯ãè«ç¹ã§ãã åãã€ã³ã¿ãŒã«å¯ŸããŠgcMoveé¢æ°ãååž°çã«åŒã³åºãã ãã§ãã ãã®ãããªã¢ã«ãŽãªãºã ã¯ãæ·±ãã®ã°ã©ãèµ°æ»ã«å¯Ÿå¿ããŸãã ãã ããããã¯æè¯ã®éžæã§ã¯ãããŸããã
ã¬ããŒãžã³ã¬ã¯ã¿ãŒãã³ããŒããããšã®ãã©ãŒæ©èœã¯ãåç §ã«ãã£ãŠããŒã«ãªãã£ãç¶æããæ©èœã§ãã èŠããã«ãçžäºã«åç §ãããªããžã§ã¯ããšã¡ã¢ãªå ã®ãªããžã§ã¯ãã¯ãã§ããéãè¿ããã®ã§ãªããã°ãªããŸããã ãã®ãããããã»ããµã¯ãã£ãã·ã¥ã¡ã¢ãªãããå¹ççã«äœ¿çšã§ããŸãã
é衚瀺ã®ããã¹ã
å®éšãè¡ãããšãã§ããŸãã ãªã³ã¯ãªã¹ããäœæããä»»æã®å Žæã«èŠçŽ ãæ¿å
¥ãå§ããŸãã ãããŠããªã¹ãå
šäœãå°å·ããŠãã ããã ãããããC ++ããã°ã©ã ã¯ã匷å¶çãªã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã®åŸãJavaãŸãã¯CïŒãããæåŸã®ã¹ãããã«æéãããããŸãã ããã¯ãC ++ã®å Žåãããã»ããµããã£ãã·ã¥ãã¹ã§åžžã«ããã¯ããäœéã®RAMããã®ããŒã¿ãå°çããã®ãåŸ
ã€ãšããäºå®ã«ãããã®ã§ãã Javaã®å Žåãããã¯ã»ãšãã©ã¢ã¬ã€å
šäœã®ãã€ãã¹ã«ãªããŸãã
ç§ã®GCã¯ããã§ã¯ãããŸããã åçŽãã®ãããæ·±ãã®ãã€ãã¹ãéžæããŸããã widthã®ãã©ããŒãµã«é åºã§ãªããžã§ã¯ãã移åããããšããå§ãããŸãã æé©ãªãã¹æ°ãéæããããã«ã ãã®ã¢ã«ãŽãªãºã ã®ããã«ããªããžã§ã¯ããžã®ã¢ã¯ã»ã¹ã®çµ±èšã«åŸã£ãŠæ··ä¹±ããŠãªããžã§ã¯ããã¡ã¢ãªå ã«æ§ç¯ããããšã¯éåžžã«ã¯ãŒã«ã§ãã
ããã ãã§ã ã³ã¬ã¯ã¿ãŒãšã®äœæ¥ãå®èšŒããããã«æ®ã£ãŠããŸãã
æãåçŽãªæ€çŽ¢ããªãŒãäŸãšããŠåãäžããŸãã
struct searchTree { gcHeader gc; searchTree* left; searchTree* right; int key; static const int refCount = 2; };
æ¢ã«è¿°ã¹ãããã«ãæåã¯èŠåºãã§ãããèŠåºãã®åŸã«ã¯ããŒãã®ãªããžã§ã¯ããžã®ãã¹ãŠã®ãã€ã³ã¿ãŒããããŸãã
void stAdd(searchTree* &target, int key){ if (target == nullptr){ target = gcAlloc<searchTree>(); target->left = target->right = nullptr; target->key = key; return; } if (target->key == key) return; if (target->key < key) stAdd(target->left, key); else stAdd(target->right, key); }
ããªãŒãžã®éåžžã®è¿œå ã gcAllocã®äœ¿çšæ¹æ³ã«æ³šæããŠãã ããã
searchTree* stFind(searchTree* target, int key){ if (target == nullptr || target->key == key) return target; if (target->key < key) return stFind(target->left, key); else return stFind(target->right, key); } void stPrint(searchTree* t, int indent = 0){ if (t == nullptr) return; for (int i = 0; i < indent; ++i) cout << " "; cout << t << ' ' << t->key << endl; stPrint(t->left, indent + 1); stPrint(t->right, indent + 1); } void stCut(searchTree* &target, int key){ if (target == nullptr || target->key == key){ target = nullptr; return; } if (target->key < key) stCut(target->left, key); else stCut(target->right, key); }
stFindã¯ç®çã®ããŒãæã€ãµãããªãŒãžã®ãªã³ã¯ãè¿ããstPrintã¯ãµãããªãŒã®ããŒãšã¢ãã¬ã¹ãåºåããstCutã¯ããŒãä¿åãããŠãããµãããªãŒãåãæšãŠãŸãã
æåŸã«ãã¡ã€ã³ã
int main(){ gcInit(); stackRef<searchTree> root; stAdd(root.ref, 2); stAdd(root.ref, 1); stAdd(root.ref, 3); stAdd(root.ref, 6); stAdd(root.ref, 5); stAdd(root.ref, 4); stAdd(root.ref, 8); stackRef<searchTree> additionalRef; additionalRef.ref = stFind(root.ref, 3); cout << "Before GC" << endl; cout << additionalRef.ref << ' ' << currentOffset << endl <<endl; stPrint(root.ref); cout << endl; gcCollect(); cout << "After GC" << endl; cout << additionalRef.ref << ' ' << currentOffset << endl << endl; stPrint(root.ref); cout << endl; stCut(root.ref, 5); gcCollect(); cout << "Deleted some elements and GC'd." << endl; cout << additionalRef.ref << ' ' << currentOffset << endl << endl; stPrint(root.ref); return 0; }
Before GC 0xd92058 224 0xd92018 2 0xd92058 3 0xd92078 6 0xd920d8 8 0xd92098 5 0xd920b8 4 0xd92038 1 After GC 0xd93108 224 0xd930e8 2 0xd93108 3 0xd93128 6 0xd93148 8 0xd93168 5 0xd93188 4 0xd931a8 1 Deleted some elements and GC'd. 0xd92038 160 0xd92018 2 0xd92038 3 0xd92058 6 0xd92078 8 0xd92098 1
ã芧ã®ãšãããããã°ã©ããŒçšã®æ§é äœã䜿çšããŠãã»ãšãã©å€ãããŸããã ããã§äœãèµ·ãã£ãŠããŸããïŒ
1.æ€çŽ¢ããªãŒãä»»æã«åããŸãã
2.ããããã®èŠçŽ ãžã®å¥ã®ã¹ã¿ãã¯ãªã³ã¯ãäœæããŠãGCã1ã€ã®ãªããžã§ã¯ããžã®è€æ°ã®ãªã³ã¯ã«ã©ã®ããã«å¿çãããã確èªããŸãã
3.ããªãŒãadditionalReferenceãcurrentOffsetãå°å·ããŸãã
4.ã¢ã€ãã«ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã
5.ããªãŒãå床å°å·ããŸãã å¿ èŠãªãã¹ãŠã®ãã€ã³ã¿ãŒãå€æŽãããŸããã
6. 1ã€ã®ãµãããªãŒãããªãã³ã°ããŠãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãå床åŒã³åºããŸãã ãã¹ãŠãæ£åžžã«æ©èœããŸãã currentOffsetãæžå°ããããªãŒã®ã«ãŒããåããŠã¢ã¯ã»ã¹ããã®ãšåãã¢ãã¬ã¹ã«æ»ã£ãããšã«æ³šæããŠãã ããã
çµè«
ãããã£ãŠãC ++ã§ã¯ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã䜿çšã§ããŸãã ããã«ãæå³çãªæèŠã§ã¯ããªãŒããŒããããæå°éã§ãã£ãŠããããªããããã§ãã æ¬åœã«äŸ¿å©ã§åœ¹ç«ã€ããã«ãå®è¡ããå¿ èŠããããã¹ãŠã®ãã®ããªã¹ãããããšããŸãã
ãŸããçµç¹ã®ãã€ã³ãã
1.ã°ããŒãã«å€æ°-ãã¡ãããããã¯ãŸã£ããã¯ãŒã«ã§ã¯ãããŸããã ãã¹ãŠã人éã®ã¯ã©ã¹ãC ++ã¢ãã±ãŒã¿ãŒãšããŠèšèšããå¿ èŠããããŸãã
2.åã¯ã©ã¹ã«ããããŒã匷å¶ããããšã¯ã»ãšãã©ãµãã£ãºã ã§ãã getSizeãšgetLayoutã®2ã€ã®ã¡ãœãããå¿ èŠãªæœè±¡ã¯ã©ã¹ããç¶æ¿ããå¿ èŠããããŸãã åŸè ã¯ããã¹ãŠã®ãã€ã³ã¿ãŒã®çžå¯Ÿåº§æšãæ ŒçŽãããŠããé åãžã®åç §ãè¿ãå¿ èŠããããŸãïŒããã¹ãŠã®ãªã³ã¯ãå é ã«ããããšããèãã¯ãæ·±å»ãªãã®ã«ã¯ãŸã£ããé©ããŠããŸããïŒã ãã®é åã¯ééããªãèªåçã«å ¥åãããã¯ãã§ããããããã©ã®ããã«å®è£ ã§ãããã¯ãŸã ããããŸããã
次ã®è³ªåã¯èªåã¢ã»ã³ããªã§ãã GCã®ã¢ã€ãã¢ãæå±ããããšãã誰ããgcCollecté¢æ°ã®ãããªãã®ã絶ããåŒã³åºãããšãæå³ãã人ã¯ããŸããã§ããã ãã ããC ++ã¯ç¹æ®ãªã±ãŒã¹ã§ãã å®è¡ã®æµãå šäœã錻ã®äžã§ããŸãã¯å°ãªããšãäºæž¬å¯èœãªãã®ã«ããããšã§æåã§ãã ããã§ä»ã®èšèªã®æ°ãŸãããªã¬ããŒãžã³ã¬ã¯ã¿ãŒã¯ãã»ãšãã©ã€ããªãã®ãŒç¯çœªã§ãã ãããã£ãŠãå°ãªããšã2ã€ã®ã¢ãŒããå¿ èŠã§ãã
1.éæã
2.ç¹å®ã®ã¡ã¢ãªã¯ã©ãŒã¿ã䜿ãæãããåŸãäŸå€ãã¹ããŒããŸãã ããã§ãã¡ã¢ãªã匷å¶çã«åé€ãããå²ãåœãŠããã決å®ããã®ã¯ããã°ã©ããŒæ¬¡ç¬¬ã§ãã
ãããŠãã1ã€è³ªåããããŸãã ãã«ãã¹ã¬ããã ããã§ã¯ãã¹ãŠãæªãã§ãã ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãéå§ããã«ã¯ãäœãå£ããªãããã«ãã¹ãŠã®ã¹ã¬ãããäžæããå¿ èŠããããŸãã æåŸã«ãJVMã®ååãèšè¿°ããå¿ èŠããããŸãã æè¯ã®è§£æ±ºçã¯åœŒã®äžåšã®ããã§ãã ã¹ã¬ããããšã«ãç¬èªã®å°çšGCãäœæããããšãã§ããŸããäœããå¥ã®ãµãããã»ã¹ã«è»¢éããå¿ èŠãããå Žåãéåžžã®shared_ptrããã£ã³ã»ã«ãããŠãŒã¶ãŒã¯ããŸããã å ±æã¡ã¢ãªããªããã°ãç掻ã¯éåžžã¯ããã«æ¥œããã§ãã
æ²ããã¡ã¢ã§çµãããŸãã ãã®ãããªã¬ããŒãžã³ã¬ã¯ã¿ãŒã¯ãæ¢è£œã®ã©ã€ãã©ãªãšå®å šã«äºææ§ããããŸããã 圌ãã®æœèšã¯å¿ èŠãªããŒã¿ãæäŸããããšã¯ã§ããŸãããstd :: listãstd :: mapãããã³std :: setã¯ãGCå°çšã«æžãæããå Žåã«ã®ã¿ã¡ãªããããããšããäºå®ã«ãããããããããšãã°ãNã®ã¬ãã€ãã®BoostãœãŒã¹ãããçŽãããšã¯ãŸã£ããç¡é§ã§ãããã ããå°ããªãªããžã§ã¯ãã®å Žåã«ãã©ã°ã¡ã³ããŒã·ã§ã³ã«å¯ŸåŠããã«ã¯ããã®ãããªããšã¯éåžžã«äŸ¿å©ã ãšæããŸãããããã
ããŠã³ããŒãããŠåçã§ããŸãã