è¨èªã® GC æ©è½ã¨åç §ã«ã¦ã³ã (ä¸ç·¨)
åç·¨ã§ãã¯ãã³ã¡ã³ããæ¥è¨ã³ã¡ã³ãã§
- ã©ãããã循ç°åç §ã«ãããªã¼ã¯ãåé¿ã§ããã®ãã説æãã¦ã»ãã
- PHP 5.3 㧠cycle collector ãæè¼ããããã¨ã«ã¤ãã¦ã®ãã©ãã¼ã欲ãã
ã¨ããæè¦ããã£ãã®ã§ããããé 次åãä¸ãã¦ãããã¨ã«ããã
æ¬å½ã¯ãããå¾ç·¨ã¨ãããã£ããã ãã©ãã©ãã©ãè©°ãè¾¼ã¿ããå 容ãå¢ãã¦ããã®ã§ãåæãªããä¸æ¦åã£ã¦ä¸ç·¨ãå¾ç·¨ã® 2 æ¬ç«ã¦ã¨ããã¦ããããã
SpiderMonkey 㨠XPCOM ã®ã¬ã¼ãã¸ã³ã¬ã¯ã·ã§ã³
ãã¦ãcycle collector ã¨ãã㨠Firefox 3 ããæè¼ãããã¨ãããã¨ã§æ°ã«ãªã£ã¦ãã人ãå¤ãã¨æãããã®ã§ãã¾ã㯠SpiderMonkey (JavaScript ã® Mozilla ã§ã®å®è£ ) ã§ã¯ã©ã®ãã㪠GC (ã¬ã¼ãã¸ã³ã¬ã¯ã·ã§ã³) ãè¡ãããã®ããè¦ã¦ã¿ããã
åºæ¬çã«ãSpiderMonkey 㯠Ruby ã¨åãããã¼ã¯ & ã¹ã¤ã¼ã㪠GC ãè¡ãã次ã®ãããªã³ã¼ãã xpcshell (xulrunner ãªã©ã«ä»å±*1 ) ã§èµ°ãããã¨æ¬¡ã®ãããªçµæã«ãªãã
function make_circular() { var foo = {}; var bar = {}; var baz = {}; foo['bar'] = foo; bar['baz'] = baz; baz['foo'] = foo; return foo; } for (var i = 0; i < 1000000; ++i) { make_circular(); }
% run-mozilla.sh xpcshell test.js & PID=$! && while ps -o sz -p $PID | grep -v "SZ"; do :; done [1] 12801 6733 6798 6897 6897 7007 7860 7926 ... 11381 11414 11547 11646 11680 11713 11779 11845 11879 11947 11947 11947 ... (以ä¸åãæ°å¤)
ä½ããã®é¾å¤ãè¶ããã¨ãã㧠GC ãåä½ããã¡ã¢ãªä½¿ç¨éãä¸å®ã«ä¿ããããã¨ããããã
ãã®ããã«ãPlain-Old JavaScript Object (ããã POJO ããã) ã¯ãæ£ãã GC ãããã®ã ãã©ã XPCOM *2 ãªãã¸ã§ã¯ãã JavaScript ã§æä½ããã±ã¼ã¹ã§ã¯ã¾ãéã£ãåé¡ãçºçããã
ãUsing XPCOM in JavaScript without leakingãã¨ããç§é¸ãªè¨äºã«ããããã«ãXPCOM ã§ã¯ãå¤ãã®ã³ã³ãã¼ãã³ããã¬ã¼ã ã¯ã¼ã¯åæ§ãåç §ã«ã¦ã³ããã¼ã¹ã® GC ãæ¡ç¨ãã¦ããããããXPCOM ã®ã³ã³ãã¼ãã³ãã¨ãã¦å®è£ ããã¦ããã³ã³ããã«ãJavaScript ã®ãªãã¸ã§ã¯ãã¸ã®åç §ãçªã£è¾¼ãã§å¾ªç°åç §ãä½ã£ããã©ããªãã ãããããã¡ããããã£ããã®ãã¼ã¯ & ã¹ã¤ã¼ã GC ã¯å¹ããªããªãããªã¼ã¯ãçºçãã¦ãã¾ãã ãããSpiderMonkey å´ã®ã¬ã¼ãã¸ã³ã¬ã¯ã¿ã¯ã(JavaScript ã®ãªãã¸ã§ã¯ãã¨ãã¦) æ±ã£ã¦ãã XPCOM ãªãã¸ã§ã¯ããããä»¥å¤ (ã¤ã¾ã XPCOM ãå©ç¨ãã SpiderMonkey 以å¤ã®) ã¢ã¸ã¥ã¼ã«ããåç §ããã¦ããªããã¨ã確èªãããããªãããã ã
ã§ããããæ¬å½ãã©ãããå®éã«è©¦ãã¦ã¿ãã
var nsIMutableArray = Components.interfaces.nsIMutableArray; var impl_nsIMutableArray = Components.classes['@mozilla.org/array;1']; function create_nsIMutableArray() { return impl_nsIMutableArray.createInstance().QueryInterface(nsIMutableArray); } function make_circular() { var foo = create_nsIMutableArray(); var bar = create_nsIMutableArray(); var baz = create_nsIMutableArray(); foo.appendElement(bar, false); bar.appendElement(baz, false); baz.appendElement(foo, false); return foo; } for (var i = 0; i < 1000000; ++i) { make_circular(); // if (!(i % 100000)) gc(); // <- ããã¯ããã£ã¦ããªãã¦ããã }
XPCOM ã«ã¯ãã¹ã¯ãªããä¸ã§ä½¿ãã (scriptable) ãªé©å½ãªãã£ã¯ã·ã§ããªããªãã£ãã®ã§*3ãnsMutableArray ã使ã£ããããã Mozilla 1.8 系㮠SpiderMonkey + XPConnect + XPCOM ã§èµ°ãããã¨æ¬¡ã®ãããªçµæã«ãªãã
6470 6798 6930 6963 7003 7309 7361 ... 36335 36370 36403 36403 36436 36470 36470 36503 ... (延ã å¢ãç¶ãã)
ã¾ããã¨ããããã§ãcycle collector ã®åºçªã¨ãããã¨ã«ãªãã*4
å ã®ããã°ã©ã ã Mozilla 1.9 ç³»ã®ãã©ã³ãã® xpcshell ã§èµ°ãããã¨ã次ã®ãããªçµæã«ãªã£ãããªãããã® xpcshell ã¯XULRunner ã® nightly buildã«å«ã¾ãã¦ãããã®ã ã
% ./run-mozilla.sh ./xpcshell /tmp/test2.js & PID=$! && while ps -o sz -p $PID | grep -v "SZ"; do :; done [2] 13900 911 913 913 ... (以å¾ããã£ã¨ 913)
ä½è«ã ãã©ãå¿ãªãããã¡ãã®æ¹ãå§åçã«ã¡ã¢ãªã®ãããããªã³ããå°ãããªã£ã¦ããæ°ããããããããåæã¨ãªãã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãéãå¯è½æ§ãããã®ã§ä½ã¨ããããªããããããã®éããªããããã話ã ã
ãªãã"@mozilla.org/array;1" ã cycle collector ã«å¯¾å¿ãã¦ããæ§ã¯ãmozilla/source/xpcom/ds/nsArray.cpp ã§è¦ããã¨ãã§ããã次ã®ç®æãããã ã
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsArray) NS_INTERFACE_MAP_ENTRY(nsIArray) NS_INTERFACE_MAP_ENTRY(nsIMutableArray) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray) NS_INTERFACE_MAP_END ... NS_IMPL_CYCLE_COLLECTING_ADDREF(nsArray) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsArray) NS_IMPL_CYCLE_COLLECTION_CLASS(nsArray) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsArray) tmp->Clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsArray) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mArray) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END||<
PHP 5.3 ã«æè¼ããã cycle collector
PHP 5.3 ãã®ãã®ã®ãã¤ã©ã¤ãã«ã¤ãã¦ã¯ãã¾ã£ããã¨ããã¤ã¦ã®ä¿ºã®å¤©æµã®ä¸äººã ã£ãIlia Alshanetskyæ°ã®ãIntroduction to PHP 5.3ããèªãã§ãããã¨ãã¦ãPHP ã® cycle collector ã«ã¤ãã¦ã¡ãã£ã¨éãã¦ããã
ãããã PHP ã« cycle collector ãå®è£ ãã試ã¿ã¯ 2007 年度㮠Google SOC ã®idea ã®ä¸ã¤ã¨ã㦠David Wang ã«ããè¡ããããã®ã ã2007/10/7 ã«ãããã¨ã㦠php-internals ã«æ稿ãããããããã®ä¿®æ£ã®å¾ãã¼ã¸ãããã
ãã¦ãåç·¨ã§ä½¿ã£ãã½ã¼ã¹ã³ã¼ãã PHP 5.3 ã§èµ°ããã¦ã¿ãã¨...?
array(1) refcount(1){ ["bar"]=> array(1) refcount(2){ ["baz"]=> array(1) refcount(1){ ["foo"]=> &array(1) refcount(2){ ["bar"]=> array(1) refcount(2){ ["baz"]=> array(1) refcount(1){ ["foo"]=> &array(1) refcount(2){ ["bar"]=> *RECURSION* } } } } } } } 322776 323268 323760 324252 324744 ... (以ä¸å調å¢å ãã¦ãã) 1958240 1958732 1959224 1959716 1960208 1960700 1961192 452936 (GC ãè¡ãããæ¥æ¿ã«ã¡ã¢ãªä½¿ç¨éãæ¸ã) 453004 453088 453172 453256 453340 ...
ä½ããã®é¾å¤ã«éããã¨ããã§ãGC ãåä½ãã¦ãªãã¸ã§ã¯ããéæ¾ããã¦ããããã®åä½ã¯ãã¹ã¯ãªãããèµ°ããã¦ããéããã£ã¨ç¹°ãè¿ãããã
以ä¸ã®ã¹ã¯ãªããã§ã¯ãæé»çã« GC ãåä½ããã¦ããããæ°ãã«è¿½å ãããçµã¿è¾¼ã¿é¢æ° gc_collect_cycles()
ãå¼ã³åºããã¨ã§ãæèçã« GC ãåä½ããããã¨ãã§ããã
ã¾ããæé»ç㪠GC ã®åä½ãåæ¢ / éå§ããããå ´åã¯ããããã gc_disable()
/ gc_enable()
ã使ããç¾å¨ GC ãæå¹ãã©ãã㯠gc_enabled()
ã§åå¾å¯è½ã
次å㯠cycle collector ã®å®è£ ã¨ãåé¿æ¹æ³ã«ã¤ãã¦æ¸ãäºå®ã
*1:ã¡ãªã¿ã« Ubuntu ã Debian ã¨ãã 㨠/usr/lib/xulrunner/xpcshell
*2:XPCOM (Cross Platform COM) ã¨ã¯ Firefox ãªã© Mozilla 製åã§ä½¿ããã¦ããã³ã³ãã¼ãã³ãæè¡ã§ãJavaScript ãã㯠XPConnect ã¨ããããã§ããããªãã¸ã«ãã£ã¦ãã·ã¼ã ã¬ã¹ã« XPCOM ãªãã¸ã§ã¯ãã®å©ç¨ãå¯è½ã«ãªã£ã¦ãã
*3:nsIDictionary ã¨ããã¤ã³ã¿ã¼ãã§ã¤ã¹ã¯ãããå®è£ ããªã
*4:JavaScript ãã使ãåã«ã¯é¢ä¿ãªã話ãªãã ãã©ããInterfacing with the XPCOM cycle collectorãã§èª¬æããã¦ããããã«ãããã³ã³ãããªãã¸ã§ã¯ãã®å®è£ 㧠cycle collector ã®æ©æµãåããããã«ã¯ãããã¤ãç¹å¥ãªè¨è¿°ãå¿ è¦ãªã¿ããã ã