ã¡ã¢ãªãªãŒã¯ã¯ããœãããŠã§ã¢ãšã³ãžãã¢ãªã³ã°ã«ãããŠæãéå€§ãªæ¬ é¥ã®1ã€ã§ããã¯ã©ãã·ã¥ã®ããã«å®è¡ãå³åº§ã«åæ¢ããã®ãšã¯ç°ãªããã¡ã¢ãªãªãŒã¯ã¯å©çšå¯èœãªã¡ã¢ãªãåŸã ã«æ¶è²»ããå¿çé床ãäœäžãããããµãŒãã¹ãæå³ããåèµ·åããããã¢ããªã±ãŒã·ã§ã³ãã¡ã¢ãªäžè¶³ãšã©ãŒã§çµäºããããããŸã§ãã·ã¹ãã ãåŸã ã«å£åãããŸããã¡ã¢ãªãªãŒã¯ã¯ãäž»èŠãªããã°ã©ãã³ã°èšèªãã¹ãŠã§çºçããŸããããŒã管çãå®å šã«æåã§è¡ãããCãC++ã ãã§ãªããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãã»ãšãã©ã®ã¯ãªãŒã³ã¢ãããåŠçãããã®ã®ã埮åŠãªåç §ãã§ãŒã³ã«ãã£ãŠã¡ã¢ãªã®è§£æŸã劚ããããJavaãPythonãJavaScriptãC#ãªã©ã§ãçºçããŸããAndroidã¢ã¯ãã£ããã£ã®ã€ãã³ããªã¹ããŒã®ãªãŒã¯ãJavaãµãŒãã¹ã®ç¡å¶éã®ãã£ãã·ã¥ãããŒã«ãããã¹ã¬ããããåé€ãããªãã¹ã¬ããããŒã«ã«å€æ°ãªã©ããããã¯ãã¹ãŠã¡ã¢ãªãªãŒã¯ã§ãããã·ã¹ãã ããããæããã«ãããŸã§éãã«èç©ãããŸãã
ã¡ã¢ãªãªãŒã¯ãä¿®æ£ããå¿ èŠããããŸãã?
SMART TS XL æ°çŸäžè¡ã®ã³ãŒãå ã®ã¡ã¢ãªãªãŒã¯ãæ€åºããããã®çæ³çãªãœãªã¥ãŒã·ã§ã³ã§ã
ä»ããæ¢çŽ¢ããã¡ã¢ãªãªãŒã¯ãç¹ã«åä»ãªã®ã¯ãéçºæ®µéã§ã¯ãã£ãã«è¡šé¢åããªãç¹ã§ãã30ç§éã®ãã¹ãå®è¡ã§ã¯ãäœåäžåãã®ã¡ã¢ãªã®å²ãåœãŠãšè§£æŸãè¡ãããŠãããªãŒã¯ã枬å®å¯èœãªã¬ãã«ã«éããããšã¯ãããŸãããããããåãã³ãŒããæ¬çªç°å¢ã§12æéãå®è¡ããããšããµãŒããŒãããŠã³ããŠããŸãå¯èœæ§ããããŸãããªãŒã¯ãçºçããŠããåããŠçºèŠããããŸã§ã®æéã¯æ°é±éã«ãåã¶ããšãå€ãããã®é ã«ã¯åå ãšãªã£ãã³ãããã¯æ¢ã«ããŒãžãããŠãããã³ãŒããæžããéçºè ã¯èŠèœãšãã詳现ãèŠããŠããªããããããŸãããã¡ã¢ãªãªãŒã¯ã®çºèŠãä¿®æ£ã鲿¢ã«ã¯ãæ§é ã«é¢ããç¥èãé©åãªã¿ã€ãã³ã°ã§é©åãªæ€åºããŒã«ãé©çšããããšããããŠå®å šãªã¡ã¢ãªç®¡çãåŸåãã«ããã®ã§ã¯ãªããæåããåªå çã«è¡ãèšèšç¿æ £ãçµã¿åãããããšãäžå¯æ¬ ã§ãã
ã¡ã¢ãªãªãŒã¯ãšã¯äœã§ããïŒ
ã¡ã¢ãªãªãŒã¯ãšã¯ãããã°ã©ã ãå®è¡äžã«ã¡ã¢ãªãå²ãåœãŠãåŸããã®ã¡ã¢ãªãäžèŠã«ãªã£ãåŸããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãã©ã³ã¿ã€ã ã«è§£æŸãããªãå Žåã«çºçããçŸè±¡ã§ããå²ãåœãŠãããã¡ã¢ãªãããã¯ã¯ãããšãã©ã®ã³ãŒããç©æ¥µçã«äœ¿çšããŠããªããŠããããã°ã©ã ã®ä»ã®éšåãä»ã®ããã»ã¹ããå©çšã§ããªãç¶æ ã§äºçŽããããŸãŸã«ãªããŸããé·æéå®è¡ãããã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããããè§£æŸãããªãã¡ã¢ãªãããã¯ãèç©ãããŠãããŸããå©çšå¯èœãªã¡ã¢ãªã¯åŸã ã«æžå°ããããã©ãŒãã³ã¹ãäœäžããŸããæçµçã«ãæŸçœ®ããŠãããšã·ã¹ãã ã¯ã¡ã¢ãªã䜿ãæãããããã»ã¹ã匷å¶çµäºãããŠââããŸããŸãã
IBMã®ããã°ã©ãã³ã°ããã¥ã¡ã³ãã«ãããæ£åŒãªå®çŸ©ã§ã¯ãã¡ã¢ãªãªãŒã¯ãšã¯ãã¡ã¢ãªãè§£æŸããã«ç¶ç¶çã«å²ãåœãŠãã¡ã¢ãªäœ¿çšéãæéãšãšãã«ééãªãå¢å ããããã°ã©ã ã®ããšã§ãããšãããŠããŸãããã®å®çŸ©ã¯ãçã®ãªãŒã¯ã«å¿ èŠãª2ã€ã®èŠä»¶ãããªãã¡ã察å¿ããè§£æŸã䌎ããªãå²ãåœãŠãšãæéçµéã«äŒŽãã¡ã¢ãªäœ¿çšéã®æç¶æ§ãæç¢ºã«ç€ºããŠããç¹ã§éèŠã§ããæçµçã«è§£æŸãããäžæçãªå²ãåœãŠïŒããšãé å»¶ãããšããŠãïŒã¯ãªãŒã¯ã§ã¯ãããŸãããè§£æŸãããããšãªããã³ãŒããã¹ã®å®è¡ããšã«å¢å ãç¶ããå²ãåœãŠã¯ããªãŒã¯ã§ãã
CãC++ã®ãããªæåã¡ã¢ãªç®¡çèšèªã§ã¯ã次ã®ãããªå Žåã«ã¡ã¢ãªãªãŒã¯ãçºçããŸãã malloc, callocãŸã㯠new 察å¿ãããã®ãªãã§åŒã³åºãããŸã free or deleteJavaãPythonãJavaScriptãC#ãªã©ã®ã¬ããŒãžã³ã¬ã¯ã·ã§ã³æ©èœãæã€èšèªã§ã¯ãã¡ã¢ãªãªãŒã¯ã¯ç°ãªã圢ã§çºçããŸããã¬ããŒãžã³ã¬ã¯ã¿ã¯ãæå³ããä¿æãããåç
§ã§ãã£ãŠããå°ãªããšã1ã€ã®æå¹ãªåç
§ãæ®ã£ãŠããã¡ã¢ãªãè§£æŸã§ããŸãããã¡ã¢ãªã¯å€ç«ããŠããã®ã§ã¯ãªããããã°ã©ã ãè§£æŸãå¿ããåç
§ãã§ãŒã³ã«ãã£ãŠä¿æãããŠããã®ã§ãã
ã¡ã¢ãªãªãŒã¯ãåé¡ãšãªãåå ãšã¯ïŒ
ã¡ã¢ãªãªãŒã¯ã®åœ±é¿ã¯ãç¶æ³ã«ãã£ãŠè»œåŸ®ãªãã®ãã壿» çãªãã®ãŸã§æ§ã ã§ããçåœãªã³ãã³ãã©ã€ã³ããŒã«ã«ãããå°ããªãªãŒã¯ã¯ãæ°ã¥ãããªããŸãŸã«ãªãããšããããŸããããã»ã¹ãçµäºãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ããã¹ãŠã®ã¡ã¢ãªãè§£æŸããããããªãŒã¯ã«ãã圱é¿ã¯ç®ã«èŠããŸãããäžæ¹ãæ°é±éé£ç¶ããŠå®è¡ããããµãŒããŒããã»ã¹ã«ãããåããªãŒã¯ã¯ãçå®ã«ã¡ã¢ãªäœ¿çšéãå¢å ãããŸãããªãŒã¯ã«ãã£ãŠæ¶è²»ãããRAMãå¢ããã«ã€ããŠããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯ããŒãžã³ã°ãéå§ããå¿çæéãé·ããªããæçµçã«ã¯ããã»ã¹ãã¯ã©ãã·ã¥ããããã¡ã¢ãªäžè¶³ãã©ãŒã«ãã£ãŠåŒ·å¶çµäºãããŸããã®ã¬ãã€ãã§ã¯ãªããããã€ãåäœã®ã¡ã¢ãªããæããªãçµã¿èŸŒã¿ã·ã¹ãã ã§ã¯ã1æéã«æ°ãã€ãããå¢å ããªããããªå°ããªãªãŒã¯ã§ããæ°æ¥ã§ããã€ã¹ãæ éããå¯èœæ§ããããŸãã
ã²ãŒã ã«ãããã¡ã¢ãªãªãŒã¯ã¯ãã¬ããŒãžã³ã¬ã¯ã¿ãå¢å€§ããããŒãè² è·ã管çããããšããŠè² è·ãå¢å€§ããããããã¬ãŒã ã¬ãŒãã®äœäžãã«ã¯ã€ããåŒãèµ·ãããæçµçã«ã¯ãã¬ã€ã€ãŒãã¯ã©ãã·ã¥ãšããŠå ±åãããã¡ã¢ãªäžè¶³ããšã©ãŒãçºçããŸããAndroidã¢ããªã±ãŒã·ã§ã³ã«ãããã¡ã¢ãªãªãŒã¯ã¯ããããªãŒãæ¶è²»ããã·ã¹ãã ããªãœãŒã¹ãè§£æŸããããã«ããã¯ã°ã©ãŠã³ãã¢ããªãçµäºãããåå ãšãªããŸãããã©ãŠã¶ã«ãããã¡ã¢ãªãªãŒã¯ã¯ã¿ãã®åäœé床äœäžãåŒãèµ·ãããé·æéã®äœ¿çšã«ãããŠãŠãŒã¶ãŒãããŒãžã®å¿çæ§ã®äœäžãšããŠäœæããŸãã
ã¡ã¢ãªãªãŒã¯ã®åå ãšã¯
ã¡ã¢ãªãªãŒã¯ã®åå ã¯èšèªãå®è¡ç°å¢ã«ãã£ãŠå€§ããç°ãªãããããããã¹ãŠã«å ±éããããã€ãã®æ ¹æ¬çãªãã¿ãŒã³ãååšããã
Cèšèªããã³C++èšèªã«ãããæåã¡ã¢ãªç®¡çãšã©ãŒ
C ããã³ C++ ã§ã¯ããã¹ãŠã®åçå²ãåœãŠã«ã¯æç€ºçãªè§£æŸãå¿
èŠã§ãã free or delete æ°çŸäžåå®è¡ãããã³ãŒããã¹ã§ã¯ãé倧ãªã¡ã¢ãªãªãŒã¯ãçºçããŸããæãäžè¬çãªåå ã¯æ¬¡ã®ãšããã§ãã
- ãšã©ãŒãã¹ã§ã¡ã¢ãªè§£æŸãäžè¶³ããŠããŸãã ã¡ã¢ãªãæ©æã«å²ãåœãŠãŠããäžé£ã®æäœãå®è¡ãã颿°ã¯ããšã©ãŒãçºçããå Žåãå²ãåœãŠãã¡ã¢ãªãè§£æŸããã«æ©æã«çµäºããå¯èœæ§ããããŸãããšã©ãŒãçºçããã±ãŒã¹ããŸããªå Žåããã¹ãã§ã¡ã¢ãªãªãŒã¯ãé¡åšåããªãå¯èœæ§ããããŸãã
- ãã€ã³ã¿ãŒã倱ãããŸããã å²ãåœãŠãããã¡ã¢ãªãžã®ãã€ã³ã¿ããå ã®ã¡ã¢ãªãè§£æŸãããåã«æ°ããå€ã§äžæžãããããšãå ã®å²ãåœãŠé åã«ã¢ã¯ã»ã¹ã§ããªããªããŸãã
- å
ã®ãªãœãŒã¹ãè§£æŸããã«åå²ãåœãŠãè¡ãã åŒã³åºã
realloc誀ã£ãŠå ã®ãã€ã³ã¿ãç Žæ£ããå Žåreallocnullãè¿ããšãå ã®å²ãåœãŠé åã«å°éã§ããªããªããŸãã
c
// Bug: early return on error loses the allocation
char *process_data(int size) {
char *buf = malloc(size);
if (!buf) return NULL;
if (validate(buf) < 0) {
return NULL; // BUG: buf is never freed
}
return buf;
}
// Fix: free before returning on every error path
char *process_data_fixed(int size) {
char *buf = malloc(size);
if (!buf) return NULL;
if (validate(buf) < 0) {
free(buf); // release before returning
return NULL;
}
return buf;
}
ã¬ããŒãžã³ã¬ã¯ã·ã§ã³èšèªã«ããã埪ç°åç §
ææ°ã®ã¬ããŒãžã³ã¬ã¯ã¿ã¯ãåç §ã«ãŠã³ãã§ã¯ãªãå°éå¯èœæ§ã«åºã¥ããŠåéå¯Ÿè±¡ãæ±ºå®ããŸãããªããžã§ã¯ãã¯ãã©ã®å®è¡äžã®ã³ãŒããã¹ãããå°éã§ããªãå Žåã«åé察象ãšãªããŸããããããäºãã«åç §ãåã£ãŠãããã®ã®ãã©ã®ã«ãŒãåç §ãããå°éã§ããªããªããžã§ã¯ãã®ã°ã«ãŒãã¯ãåç §ãµã€ã¯ã«ã圢æããŸããåçŽãªããŒã¯ã¢ã³ãã¹ã€ãŒãæ¹åŒã®ã³ã¬ã¯ã¿ã¯ãµã€ã¯ã«ãæ£ããåŠçããŸãããå€ãæ¹åŒãåçŽãªæ¹åŒã®ã³ã¬ã¯ã¿ãããã³åç §ã«ãŠã³ãã®ã¿ã«åºã¥ãã·ã¹ãã ã¯ãµã€ã¯ã«ãåéã§ããŸããã
ã埪ç°åç
§ã¯ã¬ããŒãžã³ã¬ã¯ã·ã§ã³èšèªã§ã¡ã¢ãªãªãŒã¯ãåŒãèµ·ããã®ãããšãã質åã¯ããã®åéã§æãæ€çŽ¢ãããŠãã質åã®1ã€ã§ãããæç¢ºãªçããå¿
èŠã§ããCPythonã§ã¯ã埪ç°åç
§ã¯ãé¢ä¿ãããªããžã§ã¯ãã __del__ æ¹æ³ãCPython ã®åŸªç°ã¬ããŒãžã³ã¬ã¯ã¿ã¯ã»ãšãã©ã®åŸªç°ãåŠçããŸããããã¡ã€ãã©ã€ã¶ãæã€ãªããžã§ã¯ããé¢ãã埪ç°ã¯ãåŸæ¥ååã§ããŸããã§ãããJava ãšææ°ã® .NET ã§ã¯ãã¬ããŒãžã³ã¬ã¯ã¿ã埪ç°ãæ£ããåŠçããŸããJavaScript ã§ã¯ãå€ãããŒãžã§ã³ã® Internet Explorer ã® DOM ã«ããã埪ç°åç
§ãã¡ã¢ãªãªãŒã¯ãåŒãèµ·ãããŠããŸãããããã¯ãJS ãšã³ãžã³ã® DOM ããŒãã®åç
§ã«ãŠã³ãã埪ç°ãåŠçããªãã£ãããã§ãã
ãã€ãœã³
# Python circular reference example
class Node:
def __init__(self, value):
self.value = value
self.parent = None
self.child = None
a = Node(1)
b = Node(2)
a.child = b # a references b
b.parent = a # b references a -- cycle formed
del a # neither a nor b collected immediately
del b # Python's cyclic GC will eventually collect them
# but __del__ on either object would block collection
# in older Python versions
éããããŠããªããªãœãŒã¹ïŒãã¡ã€ã«ãã³ãã«ãããŒã¿ããŒã¹æ¥ç¶ããœã±ãã
ãã¡ã€ã«ãã£ã¹ã¯ãªãã¿ãããŒã¿ããŒã¹æ¥ç¶ããããã¯ãŒã¯ãœã±ãããGUIãã³ãã«ãªã©ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãœãŒã¹ã¯ãã¬ããŒãžã³ã¬ã¯ã¿ã«ãã£ãŠç®¡çãããŸããããããã¯æç€ºçã«éããå¿ èŠããããŸããéããªããšããªãœãŒã¹ãªãŒã¯ãçºçãããã¡ã€ã«ãã£ã¹ã¯ãªãã¿ã®æ¯æžïŒLinuxã§ã¯ãéããŠãããã¡ã€ã«ãå€ãããŸããïŒãæ¥ç¶ããŒã«ã®æ¯æžãé«ã¹ã«ãŒããããµãŒããŒã«ããããœã±ããã®æ¯æžãšãã£ã圢ã§çŸããŸãã
ãã€ãœã³
# Bug: file handle leaked if exception occurs between open and close
def read_config(path):
f = open(path)
data = f.read()
# if processing raises an exception, f is never closed
process(data)
f.close()
# Fix: context manager guarantees closure regardless of exceptions
def read_config_fixed(path):
with open(path) as f:
data = f.read()
process(data)
ãžã£ã¯
// Java: try-with-resources guarantees closure
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
// process results
}
} // conn and stmt closed automatically, even on exception
ç¡å¶éãŸãã¯å¢å ããã³ã¬ã¯ã·ã§ã³
ééãªãæ¡å€§ãç¶ããã³ã¬ã¯ã·ã§ã³ãã€ãŸããšã³ããªã远å ãããã ãã§åé€ãããªãã³ã¬ã¯ã·ã§ã³ã¯ãã©ã®èšèªã«ãããŠãã¡ã¢ãªãªãŒã¯ã§ãããäžè¬çãªäŸãšããŠã¯ã以äžã®ãããªãã®ãããã
- åé€ããªã·ãŒãªãã§çµæãç¡æéã«ä¿åãããã£ãã·ã¥
- å€ããšã³ããªãåé€ããã«ãã¹ãŠã®ã¡ãã»ãŒãžã远å ããã€ãã³ããã°ãªã¹ã
- æ°ããæ¥ç¶ã远å ããããéããããæ¥ç¶ã¯æ±ºããŠåé€ããªãæ¥ç¶ã¬ãžã¹ããªã
ãžã£ã¯
// Bug: cache grows indefinitely -- classic Java memory leak pattern
private static final Map<String, Object> cache = new HashMap<>();
public void process(String key) {
cache.put(key, expensiveOperation(key));
// key is never removed from cache
}
// Fix: use a cache with eviction policy
private static final Map<String, Object> cache =
Collections.synchronizedMap(
new LinkedHashMap<String, Object>(1000, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry e) {
return size() > 1000; // LRU eviction at 1000 entries
}
}
);
ã€ãã³ããªã¹ããŒãšã³ãŒã«ããã¯ã®ãªãŒã¯
ãªã¹ããŒãŸãã¯ã³ãŒã«ããã¯ãã€ãã³ããœãŒã¹ã«ç»é²ãããåŸãç»é²è§£é€ãããªãå Žåãã€ãã³ããœãŒã¹ã¯ãªã¹ããŒãžã®åç §ãä¿æããŸãããã®åç §ãååšãããããä»ã®ãã¹ãŠã®åç §ãè§£æŸããããšããŠãããªã¹ããŒã¯ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã®å¯Ÿè±¡ã«ãªããŸãããããã¯ãJavaScriptãAndroidãããã³Java Swingã¢ããªã±ãŒã·ã§ã³ã«ãããã¡ã¢ãªãªãŒã¯ã®æãäžè¬çãªåå ã§ãã
ãžã£ãã¹ã¯ãªãã
// JavaScript: event listener leak
function setup() {
const handler = () => doWork();
document.addEventListener('click', handler);
// handler is never removed -- listener holds a reference forever
}
// Fix: remove listener when no longer needed
function setup() {
const handler = () => doWork();
document.addEventListener('click', handler);
return () => document.removeEventListener('click', handler); // cleanup function
}
ãžã£ã¯
// Android: Activity leaked via static listener
class MainActivity extends Activity {
private static OnDataListener listener; // static holds Activity reference
@Override
protected void onCreate(Bundle savedInstanceState) {
listener = data -> updateUI(data); // BUG: Activity can't be GC'd
dataService.register(listener);
}
@Override
protected void onDestroy() {
dataService.unregister(listener); // Fix: deregister on destroy
listener = null;
}
}
ã¹ã¬ããããŒã«ã«ã¹ãã¬ãŒãžãªãŒã¯
Javaã§ã¯ã ThreadLocal 倿°ã¯å€ãã¹ã¬ããã«ãã€ã³ãããŸããã¹ã¬ããããŒã«ãåããã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã§ã¯ãã¹ã¬ããã¯ãªã¯ãšã¹ãéã§åå©çšãããŸãã ThreadLocal å€ã¯åãªã¯ãšã¹ãåŸã«åé€ããããã¹ã¬ããã«çŽã¥ãããããŸãŸã«ãªãããªã¯ãšã¹ãéã§èç©ãããŸãã
ãžã£ã¯
// Bug: ThreadLocal not cleared -- leaks across pooled threads
private static final ThreadLocal<UserContext> context = new ThreadLocal<>();
public void handleRequest(Request req) {
context.set(new UserContext(req.getUser()));
processRequest();
// BUG: context.remove() never called
// Next request on this thread inherits previous request's context
}
// Fix: always remove in a finally block
public void handleRequest(Request req) {
try {
context.set(new UserContext(req.getUser()));
processRequest();
} finally {
context.remove(); // guarantees cleanup even on exception
}
}
C++ ã¹ããŒããã€ã³ã¿ã®èª€çš
std::shared_ptr åç
§ã«ãŠã³ãã䜿çšããŸãã2 ã€ã®ãªããžã§ã¯ããä¿æããŠããå Žå shared_ptr äºãã®åç
§ã«ãŠã³ãã¯æ±ºããŠãŒãã«ãªãããã©ã¡ããç Žå£ãããªãã
cpp
#include <memory>
struct Node {
std::shared_ptr<Node> next; // strong reference
};
// Cycle: neither node destroyed
auto a = std::make_shared<Node>();
auto b = std::make_shared<Node>();
a->next = b;
b->next = a; // cycle -- both a and b leaked
// Fix: use weak_ptr to break the cycle
struct Node {
std::weak_ptr<Node> next; // weak reference does not affect refcount
};
éçããã³ã°ããŒãã«å€æ°ã®çޝç©
éç倿°ãšã°ããŒãã«å€æ°ã¯ãããã»ã¹ã®å®è¡æéäžãã£ãšååšããŸãããããã«æ ŒçŽãããŠãããªããžã§ã¯ãããŸãã¯ãããããã¢ã¯ã»ã¹ã§ãããªããžã§ã¯ãã¯ãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã®å¯Ÿè±¡ã«ãªããŸãããã¬ãžã¹ããªãšããŠäœ¿çšãããéçãããããã©ãã·ã¥ããã«ã¡ãã»ãŒãžããããã¡ãªã³ã°ããã°ããŒãã«ãã¬ãŒãç¶æ ãèç©ããã·ã³ã°ã«ãã³ã¯ãã¹ãŠãã¬ããŒãžã³ã¬ã¯ã¿ããã¯èŠããªãæœåšçãªã¡ã¢ãªå¢å ã衚ããŠããŸãã
èšèªå¥ã®ã¡ã¢ãªãªãŒã¯
Cèšèªã«ãããã¡ã¢ãªãªãŒã¯
C ã«ã¯ã¬ããŒãž ã³ã¬ã¯ã¿ããªããå²ãåœãŠã远跡ããæšæºçãªã¡ã«ããºã ããããŸããã malloc, callocãŸã㯠realloc åŒã³åºããšãã¢ã«ããå¿
èŠããããŸã freeäž»èŠãªæ€åºããŒã«ã¯Valgrindã§ãïŒvalgrind --leak-check=full ./programïŒå®è¡æã«ã¡ã¢ãªæäœãèšæž¬ããè§£æŸãããªãã£ããã¹ãŠã®å²ãåœãŠãå ±åããŸãã AddressSanitizerïŒ-fsanitize=addressã³ã³ãã€ã«æã«æå°éã®ãªãŒããŒãããã§ã¡ã¢ãªãªãŒã¯ãæ€åºããç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ãã€ãã©ã€ã³ã«é©ããŠããŸãã
Cèšèªã«ãããæã广çãªäºé²çã¯ãæææš©ãæç¢ºã«ããããšã§ãããã¹ãŠã®ã¡ã¢ãªå²ãåœãŠã«ã¯ããããè§£æŸãã責任ãè² ãææè ãå¿ ã1人ååšãããã®æææš©ã¯ã³ã¡ã³ãã颿°ã·ã°ããã£ã«æèšãããã¹ãã§ãã
C++ã«ãããã¡ã¢ãªãªãŒã¯
C++ ã¯ãC ã®å²ãåœãŠã¢ãã«ã«ã³ã³ã¹ãã©ã¯ã¿ããã¹ãã©ã¯ã¿ãã¹ããŒããã€ã³ã¿ã远å ããŸãããªãœãŒã¹ã¯ã³ã³ã¹ãã©ã¯ã¿ã§ååŸããããã¹ãã©ã¯ã¿ã§è§£æŸããããšãã RAII (Resource Acquisition Is Initialization) ååããäž»ãªé²æ¢ã¡ã«ããºã ã§ãã std::unique_ptr (NAIST) ãš std::shared_ptr çãã€ã³ã¿ã®ä»£ããã«ããã䜿çšããããšã§ãæåã«ããã¡ã¢ãªè§£æŸã®ã»ãšãã©ã®å¿
èŠæ§ããªããªããŸããæ€åºããŒã«ãšããŠã¯ãValgrindãAddressSanitizerãããã³Windowsäžã®Visual Studioã®CRTãããã°ã©ã€ãã©ãªãªã©ããããŸãã
C++ ã§ããããåå : åºåºã¯ã©ã¹ã§ãã¹ãã©ã¯ã¿ãä»®æ³ãšããŠå®£èšãå¿ããããš (掟çã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¯åºåºãã€ã³ã¿ãä»ããŠåŒã³åºãããªã)ãçãã€ã³ã¿ãšã¹ããŒããã€ã³ã¿ãæ··åšãããããšããã㊠shared_ptr äžèšã§èª¬æããå圢åç
§ãã¿ãŒã³ã
Javaã«ãããã¡ã¢ãªãªãŒã¯
Javaã®ã¬ããŒãžã³ã¬ã¯ã¿ã¯ããŒããªããžã§ã¯ãã管çããŸãããOSãªãœãŒã¹ã¯ç®¡çããŸãããJavaã§ããèŠãããã¡ã¢ãªãªãŒã¯ã®ãã¿ãŒã³ã¯ä»¥äžã®ãšããã§ãã
- ãªããžã§ã¯ãåç §ãä¿æããéçãã£ãŒã«ã
- ç¡å¶éã®ãã£ãã·ã¥ãšã³ã¬ã¯ã·ã§ã³
- éããããŠããªãã¹ããªãŒã ãæ¥ç¶ãããã³ãªãŒããŒ
- finallyãããã¯å ã§ThreadLocal倿°ãã¯ãªã¢ãããªã
- ãªã¹ããŒç»é²ã¯åé€ãããŸãã
æ€åºããŒã«ïŒVisualVMïŒç¡æãJDKã«ä»å±ïŒãããŒããã³ãåæçšã®Eclipse Memory AnalyzerïŒMATïŒãYourKitãJProfilerãããã³JVMãã©ã° -XX:+HeapDumpOnOutOfMemoryError ã¡ã¢ãªäžè¶³ãçºçããéã«ãããŒããã³ããèªåçã«ååŸããã
Pythonã«ãããã¡ã¢ãªãªãŒã¯
Pythonã¯ã埪ç°åç §æ€åºã«åŸªç°ã¬ããŒãžã³ã¬ã¯ã¿ãçšããåç §ã«ãŠã³ãæ¹åŒãæ¡çšããŠããŸããPythonã«ãããã¡ã¢ãªãªãŒã¯ã¯ã以äžã®åå ã§çºçããŸãã
- ééãªãå¢å€§ããé·æä¿ååã®ãã£ãã·ã¥ãŸãã¯ã¬ãžã¹ããª
- ãªããžã§ã¯ããå«ã埪ç°åç
§
__del__å€ãããŒãžã§ã³ã®Pythonã®ã¡ãœãã - ã¢ãžã¥ãŒã«ã¬ãã«ã®ã°ããŒãã«å€æ°ã«æ ŒçŽããã倧ããªãªããžã§ã¯ã
- åç §ã«ãŠã³ããé©åã«ç®¡çããªãCèšèªæ¡åŒµæ©èœ
æ€åºããŒã«ïŒ tracemalloc ïŒPython 3.4以éã«çµã¿èŸŒãŸããŠããŸãïŒ objgraph ãªããžã§ã¯ãåç
§ã°ã©ããèŠèŠåããããã«ã memory_profiler è¡ããšã®ã¡ã¢ãªæž¬å®çšã
ãã€ãœã³
import tracemalloc
tracemalloc.start()
# ... run the code under test ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)
JavaScriptã«ãããã¡ã¢ãªãªãŒã¯
JavaScriptã®ã¬ããŒãžã³ã¬ã¯ã¿ã¯å°éå¯èœæ§ãå©çšããŸããæå³ããªãåç §ã«ãã£ãŠã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã劚ãããããšãã¡ã¢ãªãªãŒã¯ãçºçããŸãã
- DOMããŒãã¯ããã¥ã¡ã³ãããåé€ãããããJavaScriptã¯ããŒãžã£ããã¯äŸç¶ãšããŠåç §ãããŠããã
- æéã®çµéãšãšãã«ããŒã¿ãèç©ãããã°ããŒãã«å€æ°
- ã¿ã€ããŒã¯ä»¥äžã§äœæãããŸãã
setInterval決ããŠã¯ãªã¢ãããªããã® - ã€ãã³ããªã¹ããŒã¯é·å¯¿åœãªããžã§ã¯ãããåé€ãããŸãã
æ€åºæ¹æ³ïŒChrome DevToolsã®ã¡ã¢ãªã¿ãïŒããŒãã¹ãããã·ã§ãããå²ãåœãŠã¿ã€ã ã©ã€ã³ïŒãFirefoxã®ã¡ã¢ãªãããã¡ã€ã©ã
ãžã£ãã¹ã¯ãªãã
// Bug: interval holds reference to elements indefinitely
const elements = [];
const interval = setInterval(() => {
elements.push(document.createElement('div')); // grows forever
}, 100);
// Fix: clear interval when done
clearInterval(interval);
elements.length = 0; // release array contents
C#ã«ãããã¡ã¢ãªãªãŒã¯
C#ãš.NETã¯äžä»£å¥ã¬ããŒãžã³ã¬ã¯ã¿ã䜿çšããŸããã¡ã¢ãªãªãŒã¯ã¯æ¬¡ã®ãããªå Žåã«çºçããŸãã
- é·æéåç¶ãããªããžã§ã¯ãã«ç»é²ãããã€ãã³ããã³ãã©ã¯ãç»é²è§£é€ãããŠããŸããã
- ééãªãæé·ããéçã³ã¬ã¯ã·ã§ã³
- 管çãããŠããªããªãœãŒã¹ã¯ã
IDisposable - é »ç¹ãªå€§èŠæš¡å²ãåœãŠã«ããã©ãŒãžãªããžã§ã¯ãããŒãïŒLOHïŒã®æçå
æ€åºæ¹æ³ïŒè©³çްãªGCåæã«ã¯ãdotMemoryãVisual Studio蚺æããŒã«ãPerfViewã䜿çšããŸãã
Cã·ã£ãŒã
// Fix: implement IDisposable for explicit resource cleanup
public class DatabaseConnection : IDisposable {
private SqlConnection _connection;
private bool _disposed = false;
public DatabaseConnection(string connectionString) {
_connection = new SqlConnection(connectionString);
}
public void Dispose() {
if (!_disposed) {
_connection?.Dispose();
_disposed = true;
}
}
}
// Use with 'using' to guarantee Dispose is called
using (var conn = new DatabaseConnection(connectionString)) {
// use connection
} // Dispose called here automatically
ã¡ã¢ãªãªãŒã¯æ€åºïŒããŒã«ãšãã¯ããã¯
èšèªå¥æ€åºããŒã«
| èšèª | ããŒã« | æ€åºãããã® |
|---|---|---|
| C / C ++ | ãŽã¡ã«ã°ãªã³ãïŒMemcheckïŒ | ããŒããªãŒã¯ãç¡å¹ãªèªã¿æžããè§£æŸåŸäœ¿çš |
| C / C ++ | AddressSanitizer | ã¡ã¢ãªãªãŒã¯ããããã¡ãªãŒããŒãããŒãè§£æŸåŸäœ¿çšãé«éã©ã³ã¿ã€ã |
| C + + | ã¡ã¢ãªãŒå士 | Windows/Linuxã®ããŒãããã³ãã³ãã«ãªãŒã¯ |
| Java | Eclipse MAT | ããŒããã³ãè§£æãããããŒã¿ãŒããªãŒããªãŒã¯å®¹çè |
| Java | VisualVM | ãªã¢ã«ã¿ã€ã ããŒãç£èŠãGCåäœãã¹ã¬ããåæ |
| Java | JProfiler / YourKit | 詳现ãªå²ãåœãŠè¿œè·¡æ©èœãåããåçšãããã¡ã€ã©ãŒ |
| Python | ãã¬ãŒã¹ããã㯠| Python 3.4以éãçµã¿èŸŒã¿ã®ã¡ã¢ãªå²ãåœãŠãã¬ãŒã¹æ©èœãæèŒãããŠããŸãã |
| Python | ãªããžã§ã¯ãã°ã©ã | ãªããžã§ã¯ãåç §ã°ã©ãã®å¯èŠå |
| Python | ã¡ã¢ãªãããã¡ã€ã©ãŒ | è¡ããšã®ã¡ã¢ãªæž¬å® |
| JavaScriptã | Chrome DevTools | ããŒãã¹ãããã·ã§ãããå²ãåœãŠã¿ã€ã ã©ã€ã³ãä¿æãµã€ãº |
| C# / .NET | ãããã¡ã¢ãª | ãªããžã§ã¯ãä¿æãã¬ããŒãžã³ã¬ã¯ã·ã§ã³åæ |
| C# / .NET | ããã©ãŒãã³ã¹ãã¥ãŒ | GCã€ãã³ããå²ãåœãŠã¹ã¿ãã¯ãã¡ã¢ãªè² è· |
| ãã¹ãŠ / å¶äœ | ãã¥ãŒã¬ãªãã¯ãããŒã¿ããã°ããã€ããã¬ãŒã¹ | ç¶ç¶çãªã¡ã¢ãªç£èŠãç°åžžæ€ç¥ |
ã¡ã¢ãªãªãŒã¯ãèŠã€ããæ¹æ³ïŒæ®µéçãªã¢ãããŒã
ã¹ããã1ïŒæŒæŽ©ç®æã確èªããã ã¢ããªã±ãŒã·ã§ã³ãéåžžã®è² è·ã§å®è¡ããã·ã¹ãã ããŒã«ã䜿çšããŠæéã®çµéã«äŒŽãã¡ã¢ãªäœ¿çšéãç£èŠããŸã (top, htopïŒã¿ã¹ã¯ãããŒãžã£ãŒãç£èŠããã·ã¥ããŒããªã©ïŒã¡ã¢ãªäœ¿çšéãå®å®ããã«ç¶ç¶çã«å¢å ããå Žåã¯ãã¡ã¢ãªãªãŒã¯ãçºçããŠããå¯èœæ§ãé«ãã§ãã
ã¹ããã2ïŒã¡ã¢ãªãªãŒã¯ãçºçããŠããã³ãŒããã¹ãç¹å®ããŸããã¡ã¢ãªå¢å ãšçžé¢ããæäœãç¹å®ããŸããç¹å®ã®ã¯ãŒã¯ãããŒïŒãã°ã€ã³ããã¡ã€ã«ã¢ããããŒããæ€çŽ¢ã¯ãšãªãªã©ïŒãç¹°ãè¿ãå®è¡ããåå埩åŠçã§ã¡ã¢ãªãå¢å ãããã©ããã芳å¯ããããšã§ããã®ã¯ãŒã¯ãããŒãç¹å®ã§ããŸãã
ã¹ããã3ïŒå®è¡ååŸã®ããŒãã¹ãããã·ã§ãããååŸããŸãããããã¡ã€ã©ã䜿çšããŠãçãããã¯ãŒã¯ãããŒãè€æ°åç¹°ãè¿ãååŸã«ã¹ãããã·ã§ãããååŸããŸããã¹ãããã·ã§ãããæ¯èŒããŠãã©ã®ãªããžã§ã¯ããèç©ãããŠããããç¹å®ããŸãã
ã¹ããã4ïŒåç §ãã§ãŒã³ããã¬ãŒã¹ããŸããã»ãšãã©ã®ãããã¡ã€ãªã³ã°ããŒã«ã¯ãä¿æããªãŒã衚瀺ããŸããããã¯ããªããžã§ã¯ããã¡ã¢ãªã«æ®ã£ãŠããçç±ãšãã©ã®ã«ãŒãåç §ããªããžã§ã¯ããä¿æããŠãããã瀺ããŸãããã®ãã§ãŒã³ããã©ã£ãŠãä¿æåç §ãäœæããã³ãŒããèŠã€ããŸãã
ã¹ããã5ïŒä¿®æ£ãšæ€èšŒãçãããåå ãä¿®æ£ããåŸãã¹ãããã·ã§ããã®æ¯èŒãå床å®è¡ããŸããã¯ãŒã¯ãããŒã®åå埩åŸã«ãªããžã§ã¯ãæ°ãå¢å ããªãããšã確èªããŸãã
ã¡ã¢ãªãçµæçã«ç£èŠããïŒç·©ãããªã¡ã¢ãªãªãŒã¯ãæ€åºãã
1æéã«æ°ãããã€ãããæŒæŽ©ããªããããªäœéãªã¡ã¢ãªãªãŒã¯ã¯ãçæéã®ãã¹ãå®è¡ã§ã¯æ€åºãããŸããããã®ãããé·æéã®ç£èŠãå¿ èŠã§ããã¡ã¢ãªäœ¿çšéã宿çã«è¿œè·¡ãã䜿çšéãåºæºå€ãè¶ ããå Žåãå®çŸ©ãããã¬ãŒããè¶ ããŠå¢å ããå Žåã«ã¢ã©ãŒããçºããããã«ãç£èŠã·ã¹ãã ãèšå®ããŠãã ãããæ¬çªç°å¢ã§ã¯ãDatadogãNew RelicãDynatraceãªã©ã®APMããŒã«ããã¢ã©ãŒãæ©èœãšå±¥æŽæ¯èŒæ©èœãåããç¶ç¶çãªã¡ã¢ãªç£èŠãæäŸããŸãã
ã¡ã¢ãªãªãŒã¯ãé²ãæ¹æ³
æ§é åããããªãœãŒã¹ç®¡çã䜿çšãã
ã©ã®ããã°ã©ãã³ã°èšèªã«ãããªãœãŒã¹ã確å®ã«ã¯ãªãŒã³ã¢ããããä»çµã¿ãåãã£ãŠããŸãããããåžžã«æŽ»çšããŸãããã
- C ++ïŒ RAIIãã³ã³ã¹ãã©ã¯ã¿ã§ååŸãããã¹ãã©ã¯ã¿ã§è§£æŸããŸãã
std::unique_ptr(NAIST) ãšstd::shared_ptrããŒãã¡ã¢ãªçšãããã³ãã¡ã€ã«ãã³ãã«ãšãœã±ããçšã®ã«ã¹ã¿ã RAIIã©ãããŒã - JavaïŒ
try-with-resourcesã®AutoCloseableãªãœãŒã¹ã - PythonïŒ
withãã¡ã€ã«ãããã¯ãããã³ããŒã¿ããŒã¹æ¥ç¶ã®ããã®ã¹ããŒãã¡ã³ãïŒã³ã³ããã¹ããããŒãžã£ïŒã - CïŒïŒ
usingã«å¯Ÿãã声æIDisposableãªããžã§ã¯ãã - JavaScriptïŒ æç€ºçãªã¯ãªãŒã³ã¢ãã颿°ã
WeakRef(NAIST) ãšFinalizationRegistryãã£ãã·ã¥çšã
ãªã¹ããŒãšã³ãŒã«ããã¯ã®ç»é²è§£é€
ãã¹ãŠã®ç»é²ã«å¯ŸããŠãç»é²è§£é€ã察å¿ãããŠãã ãããã³ã³ããŒãã³ãããŒã¹ã®ãã¬ãŒã ã¯ãŒã¯ïŒReactãAndroidãAngularãQtïŒã§ã¯ãã³ã³ããŒãã³ãã®ãã£ã¢ããŠã³ã©ã€ããµã€ã¯ã«ã¡ãœããå
ã§ç»é²è§£é€ãå®è¡ããŠãã ããã useEffect React ã®ã¯ãªãŒã³ã¢ããã onDestroy Androidã§ã¯ã ngOnDestroy Angular ã§ã¯ããã¹ãã©ã¯ã¿ãŸã㯠disconnectedCallback ãŠã§ãã³ã³ããŒãã³ãã«ãããŠã
埪ç°åç §ãè§£é€ãã
2ã€ã®ãªããžã§ã¯ããäºããåç §ããå¿ èŠãããå Žåã¯ãäžæ¹åã®åŒ±ãåç §ã䜿çšããŸããã»ãšãã©ã®ããã°ã©ãã³ã°èšèªã§ã¯ããã®æ©èœãæäŸãããŠããŸãã
- PythonïŒ
weakref.ref()orweakref.WeakValueDictionary - C ++ïŒ
std::weak_ptr - JavaïŒ
java.lang.ref.WeakReference - CïŒïŒ
WeakReference<T> - JavaScriptïŒ
WeakMap,WeakSet,WeakRef
ãã£ãã·ã¥ã«è¿œæŸããªã·ãŒãå®è£ ãã
æå€§ãµã€ãºã®ãªããã£ãã·ã¥ã¯ã¡ã¢ãªãªãŒã¯ã®å¯èœæ§ããããŸããå¶éã匷å¶ããããŒã¿æ§é ã䜿çšããŸã: Java ã® LRU ãã£ãã·ã¥ (LinkedHashMap ã removeEldestEntry), functools.lru_cache Pythonã§ã¯ã WeakHashMap 远跡ããããªããžã§ã¯ãã®ã©ã€ããµã€ã¯ã«ã«ãã£ãŠããŒä»ãããããã£ãã·ã¥ããŸã㯠Caffeine (Java)ãcachetools (Python) ãªã©ã®å°çšãã£ãã·ã¥ã©ã€ãã©ãªã node-lru-cache (JavaScript)
CI/CDã«ã¡ã¢ãªãã¹ããçµã¿èŸŒã
ã¡ã¢ãªãªãŒã¯æ€åºã¯ãã³ãŒãã倿Žããããã³ã«èªåçã«å®è¡ãããã¹ãã§ãã
- C/C++ã®ãã«ãããã³ãã¹ããã€ãã©ã€ã³ã«ValgrindãŸãã¯AddressSanitizerã远å ãã
- ããŒãã¹ãããã·ã§ããã®æ¯èŒã§äºæããªããªããžã§ã¯ãã®å¢å ã瀺ãããå Žåã¯ããã«ãã倱æãããã
- ã
pytest-memrayorpytest-leaksPythonãã¹ãã¹ã€ãŒãçš - ã¡ã¢ãªç£èŠãæå¹ã«ããç¶æ ã§ã¹ããŒãžã³ã°ç°å¢ã§è² è·ãã¹ããå®è¡ãããããå€éåãçºçããå Žåã¯ãã¹ãã倱æãããã
圱é¿åæãéçã³ãŒãåæã®æèã§æ€èšãããŠããããã«ãç¹å®ã®ãªãœãŒã¹ã®ã©ã€ããµã€ã¯ã«ã«å€æŽãå ããåã«ããã®ãªãœãŒã¹ã管çããã³ãŒãã®å šç¯å²ãææ¡ããããšã¯ãã¡ã¢ãªç®¡çã«ããããªã°ã¬ãã·ã§ã³ãé²ãããã«äžå¯æ¬ ã§ããäŸåé¢ä¿ã°ã©ãåæã§èª¬æãããŠããããã«ãã©ã®ã³ã³ããŒãã³ããå ±æãªãœãŒã¹ã«äŸåããŠããããçè§£ããããšã¯ãå²ãåœãŠãšè§£æŸã®ãã¿ãŒã³ãå®å šã«å€æŽããããã®åææ¡ä»¶ãšãªããŸãã
ç¹å®ã®ç¶æ³ã«ãããã¡ã¢ãªãªãŒã¯
ã²ãŒã ã«ãããã¡ã¢ãªãªãŒã¯
ã²ãŒã ã¯ãæµã®åºçŸãšæ»äº¡ãã¬ãã«ã®èªã¿èŸŒã¿ãšã¢ã³ããŒããæ¯ç§æ°åãã®ãªããžã§ã¯ããçæããããŒãã£ã¯ã«ãšãã§ã¯ããªã©ããªããžã§ã¯ãã®çæãšç Žå£ãç¶ç¶çã«è¡ããããããã¡ã¢ãªãªãŒã¯ãçºçãããããã²ãŒã ã«ãããã¡ã¢ãªãªãŒã¯ã¯ãåŸã ã«ããã©ãŒãã³ã¹ãäœäžãããã¬ãŒã ã¬ãŒããäžæããæçµçã«ã¯ã¡ã¢ãªäžè¶³ã«ããã¯ã©ãã·ã¥ãåŒãèµ·ããã
äžè¬çãªã²ãŒã ã®ã¡ã¢ãªãªãŒã¯ãã¿ãŒã³ïŒ
- èŠèŠçã«ã¯ç Žå£ãããããå éšã¬ãžã¹ããªãã€ãã³ãã·ã¹ãã ããã¯åé€ãããªãã²ãŒã ãªããžã§ã¯ã
- ã·ãŒã³é·ç§»åŸã«ãã¯ã¹ãã£ãã¡ãã·ã¥ãã¢ã³ããŒããããªãããã«ããã¢ã»ããåç §
- ç©çãšã³ãžã³ãªããžã§ã¯ãã¯ããšã³ãã£ãã£ãç Žæ£ããããšãã«æç€ºçã«è§£æŸãããªãã
- ã°ã©ãã£ãã¯ã¹APIåŒã³åºãæã«ã·ã§ãŒããŒãŸãã¯GPUãªãœââãŒã¹ãã³ãã«ããªãŒã¯ãã
ã²ãŒã ã«ãããæ€åºã«ã¯ããšã³ãžã³åºæã®ããŒã«ïŒUnity ProfilerãUnreal Insightsãªã©ïŒãšæšæºçãªããŒããããã¡ã€ã©ã®äž¡æ¹ã䜿çšãããŸããã·ãŒã³ã®ããŒãéã®ã¹ãããã·ã§ããæ¯èŒã¯ç¹ã«å¹æçã§ããã¬ãã«ã®ããŒããšã¢ã³ããŒãåŸã®ããŒããµã€ãºã¯ãããŒãåãšã»ãŒåããµã€ãºã«æ»ãã¯ãã§ãã
çµã¿èŸŒã¿Cèšèªããã³ãããã¯ãŒã¯ããã°ã©ãã³ã°ã«ãããã¡ã¢ãªãªãŒã¯
çµã¿èŸŒã¿ã·ã¹ãã ã¯ãã¡ã¢ãªå®¹éãåºå®ãããŠãããããããã¯éåžžã«å¶éãããŠããŸãããã€ã¯ãã³ã³ãããŒã©ã®RAM容éã¯2KBãã256KBçšåºŠã§ãããã¹ã¯ãããã·ã¹ãã ã§ã¯1åã®æäœã§10ãã€ãå¢å ãããããªã¡ã¢ãªãªãŒã¯ã§ããçµã¿èŸŒã¿ããŒããŠã§ã¢ã§ã¯èŽåœçãªåé¡ãšãªããŸãããã®ãããçµã¿èŸŒã¿ç°å¢ã§ã¯ãæ€åºãããäºé²ââãéèŠã§ãããªããªããã¡ã¢ãªãªãŒã¯ãæ€åºå¯èœã«ãªã£ãæç¹ã§ãã·ã¹ãã ãæ¢ã«æ éããŠããå¯èœæ§ãããããã§ãã
çµã¿èŸŒã¿Cèšèªã«ãããã¡ã¢ãªãªãŒã¯ã®é²æ¢ïŒ
- å¯èœãªéããåçå²ãåœãŠã¯å®å
šã«é¿ããããã«ããŠãã ããã åºå®ãµã€ãºã®éçãŸãã¯ã¹ã¿ãã¯å²ãåœãŠãããã¡ã䜿çšããŸããåçå²ãåœãŠã¯
mallocçµã¿èŸŒã¿ã·ã¹ãã ã«ãããŠã¯ãããã¯å±éºã§ãããå€ãã®å Žåäžå¿ èŠã§ããã - åçãªã¡ã¢ãªå²ãåœãŠãå¿
èŠãªå Žåã¯ãåºå®ãµã€ãºã®ã¡ã¢ãªããŒã«ã䜿çšããŠãã ããã èµ·åæã«ã¡ã¢ãªãããã¯ãå²ãåœãŠãã·ã¹ãã ã®æ±çšã¢ãã±ãŒã¿ãåŒã³åºããªãããŒã«ã¢ãã±ãŒã¿ã§ç®¡çãã
malloc. - ãã¹ãŠã®å²ãåœãŠã«ã¯ãææžåãããææè
ãšãªãªãŒã¹çµè·¯ããããŸãã 察å¿ããèšç»ãªãã«äžæçãªå²ãåœãŠãè¡ãã¹ãã§ã¯ãªã
freeåãã³ãŒããã¹å ããŸãã¯ææžåãããã¯ãªãŒã³ã¢ãã颿°å ã
ãããã¯ãŒã¯ããã°ã©ãã³ã°ã«ããããªãœãŒã¹ãªãŒã¯é²æ¢ã«ã¯ããœã±ãããã³ãã«ããã¡ã€ã«ãã£ã¹ã¯ãªãã¿ããããã¡å²ãåœãŠã«å¯ŸããŠãåæ§ã®èŠåŸãé©çšããå¿
èŠããããŸããéãããœã±ããã¯ãã¹ãŠéããªããã°ãªããããããã¯ãŒã¯I/Oçšã«å²ãåœãŠããããããã¡ã¯ãã¹ãŠè§£æŸããªããã°ãªããããããã¯ãŒã¯ããŒã¿ã®èªã¿åãçšã«ååŸãããã¡ã€ã«ãã£ã¹ã¯ãªãã¿ã¯ãã¹ãŠè§£æŸããªããã°ãªããŸããã SO_REUSEADDR (NAIST) ãš SO_REUSEPORT é©åãªãœã±ããééã®ä»£ããã«ã¯ãªããŸããã
ã¡ã¢ãªãªãŒã¯ããã³ã°ãªã³ã°ãã€ã³ã¿ããããã¡ãªãŒããŒãããŒ
ããã3ã€ã¯ãããããã¡ã¢ãªç®¡çã®èª€ãã«é¢ããããæ··åãããã¡ã§ãããããããç°ãªãåé¡ã§ãã
| åé¡ | çµæ | |
|---|---|---|
| ã¡ã¢ãªãŒãªãŒã¯ | å²ãåœãŠãããã¡ã¢ãªã¯æ±ºããŠè§£æŸãããªã | ã¡ã¢ãªæ¯æžãåŸã ã«é²è¡ããOOMã¯ã©ãã·ã¥ãçºçããã |
| ã¶ãäžãããã€ã³ã¿ | ãã€ã³ã¿ãæ¢ã«è§£æŸãããã¡ã¢ãªãåç §ããŠãã | æªå®çŸ©ã®åäœãã¯ã©ãã·ã¥ãã»ãã¥ãªãã£èåŒ±æ§ |
| ãããã¡ãªãŒããŒãã㌠| å²ãåœãŠããããããã¡ã®ç¯å²ãè¶ ããŠæžã蟌ã | 飿¥ã¡ã¢ãªã®ç Žæãã»ãã¥ãªãã£èåŒ±æ§ |
ã¡ã¢ãªãªãŒã¯ã¯ãããã°ã©ã ãæéãšãšãã«éå°ãªã¡ã¢ãªãæ¶è²»ããåå ãšãªããŸãããã³ã°ãªã³ã°ãã€ã³ã¿ã¯ãããã°ã©ã ãæ¢ã«ææããŠããªãã¡ã¢ãªé åã«ã¢ã¯ã»ã¹ããŠããŸãåå ãšãªãããã®é åã«ã¯å¥ã®ã¡ã¢ãªå²ãåœãŠã«ãã£ãŠæžã蟌ãŸããä»»æã®ããŒã¿ãå«ãŸããŠããå¯èœæ§ããããŸãããããã¡ãªãŒããŒãããŒã¯ã飿¥ããã¡ã¢ãªé åãç Žæãããäºæãã¬åäœãåŒãèµ·ãããããæ»æè ãå¶åŸ¡ããŒã¿ãäžæžããããããããšãå¯èœã«ããŸãã
ããã3ã€ã¯ãã¹ãŠãã¡ã¢ãªæäœãèšæž¬ããå®è¡æã«éåãå ±åããC/C++ã®AddressSanitizerã§æ€åºå¯èœã§ãã
ã¡ã¢ãªãªãŒã¯ã®ã³ãŒãäŸ
CïŒæŒæ°Žç®æãå®å šã«å¡ã
c
#include <stdlib.h>
#include <string.h>
// Bug: user->name is never freed before user itself
typedef struct {
char *name;
int age;
} User;
User *create_user_buggy(const char *name, int age) {
User *user = malloc(sizeof(User));
user->name = strdup(name); // allocates a copy of name
user->age = age;
return user;
}
void free_user_buggy(User *user) {
free(user); // BUG: user->name leaked
}
// Fix: free nested allocations before the container
void free_user_fixed(User *user) {
if (user) {
free(user->name); // free nested allocation first
free(user); // then free the container
}
}
Java: ãªã¹ããŒã®ãªãŒã¯ãšä¿®æ£
ãžã£ã¯
import java.util.ArrayList;
import java.util.List;
// Bug: listeners registered but never removed
public class EventBus {
private static final List<Runnable> listeners = new ArrayList<>();
public static void register(Runnable listener) {
listeners.add(listener);
}
// Fix: provide a deregistration method
public static void unregister(Runnable listener) {
listeners.remove(listener);
}
}
// Usage -- always pair register with unregister
public class MyComponent {
private final Runnable listener = this::onEvent;
public void attach() {
EventBus.register(listener);
}
public void detach() {
EventBus.unregister(listener); // ensures no retained reference
}
private void onEvent() {
// handle event
}
}
C++: RAIIãªãœãŒã¹ãããŒãžã£
cpp
#include <cstdio>
#include <stdexcept>
// RAII wrapper: file is closed when FileHandle goes out of scope
class FileHandle {
FILE *file_;
public:
explicit FileHandle(const char *path, const char *mode)
: file_(std::fopen(path, mode)) {
if (!file_) throw std::runtime_error("Cannot open file");
}
~FileHandle() { std::fclose(file_); } // destructor guarantees close
// Disable copy to prevent double-close
FileHandle(const FileHandle&) = delete;
FileHandle &operator=(const FileHandle&) = delete;
FILE *get() const { return file_; }
};
void process_file(const char *path) {
FileHandle fh(path, "r"); // opened here
// use fh.get() ...
} // ~FileHandle() called here automatically -- file closed even on exception
Python: tracemalloc ãªãŒã¯æ€åº
ãã€ãœã³
import tracemalloc
def leaking_function():
data = []
for _ in range(10000):
data.append("x" * 1000) # 10MB allocated, never freed
return None # data goes out of scope here but items may be cached
tracemalloc.start()
leaking_function()
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics("lineno")
print("Top memory consumers:")
for stat in top_stats[:5]:
print(stat)
èªå®æ¡ä»¶ SMART TS XL å€§èŠæš¡ãªã¡ã¢ãªãªãŒã¯ãæ€åº
æåã«ããã³ãŒãã¬ãã¥ãŒãšã©ã³ã¿ã€ã ãããã¡ã€ãªã³ã°ã¯ã©ã¡ããã³ãŒãã®å®è¡ãå¿ èŠãšããã¬ãã¥ãŒæ åœè ãããŒã«ã1åã®ã»ãã·ã§ã³ã§ç¢ºèªã§ããç¯å²ã«éå®ãããŸããéçè§£æã¯ãå®è¡åã®ã³ãŒãæ§é ãã³ãŒãããŒã¹å šäœã«ããã£ãŠåæã«æ€æ»ããã¡ã¢ãªãªãŒã¯ãå®éã«å®è¡æã«çºçããå¿ èŠãªããã¡ã¢ãªãªãŒã¯ã®åå ãšãªãããšãç¥ãããŠãããã¿ãŒã³ãç¹å®ããŸãã
SMART TS XL ç°å¢å ã®ããããèšèªã®ãœãŒã¹ã³ãŒããåã蟌ã¿ãã³ãŒãããŒã¹å šäœã«ãããå²ãåœãŠãšè§£æŸã®é¢ä¿ã衚ãçµ±äžãããçžäºåç §ã¢ãã«ãæ§ç¯ããŸãã以äžãèå¥ããŸãã
- å²ãåœãŠãµã€ãïŒåŒã³åºãå
ïŒ
malloc,new,open,connectïŒããã³åèšèªã«ããããããã«çžåœãããã®ïŒå°éå¯èœãªãã¹ãŠã®ã³ãŒããã¹ã«å¯Ÿå¿ããè§£æŸããªã - ãªãœãŒã¹ãåã«å²ãåœãŠãããäŸå€åŠçãã¹
throwããããæç²æã«ãªãªãŒã¹ããããæçµçã« - æéã®çµéãšãšãã«èç©ããããªããžã§ã¯ããžã®åç §ãä¿æããéçãã£ãŒã«ãããã³ã°ããŒãã«ãã£ãŒã«ã
- ã³ã³ããŒãã³ãã®ã©ã€ããµã€ã¯ã«ã«ãããŠå¯Ÿå¿ããç»é²è§£é€ããªããªã¹ããŒç»é²åŒã³åºã
ThreadLocal.set察å¿ããåŒã³åºãããªãremovefinallyãããã¯å ã§
ãã®ãã©ãããã©ãŒã ã®éçã³ãŒãåææ©èœã¯ãéçºè ãæ°çŸè¡ãæåã§æ€æ»ããã®ã«ãããæéã§ãæ°çŸäžè¡ã®ã³ãŒãå šäœã«ãããã®æ€åºçµæãåäžã«é©çšããŸãããã¿ãŒã³ãç¹å®ããããšãåæçµæã¯ãå²ãåœãŠãè§£æŸãããªãçç±ã瀺ãã³ãŒããã¹ãšãšãã«ãç¹å®ã®ãã¡ã€ã«ãè¡ãå²ãåœãŠç®æãè¿ããŸããããã«ãããéçºè ã¯åãªããã©ã°ã®ãªã¹ãã§ã¯ãªããåé¡ãä¿®æ£ããããã«å¿ èŠãªã³ã³ããã¹ããåŸãããšãã§ããŸãã
COBOLãJCLãããã³ææ°ã®ã¢ããªã±ãŒã·ã§ã³ã³ãŒãããã¹ãŠçžäºäœçšããã¬ã¬ã·ãŒã·ã¹ãã ã®å Žåã SMART TS XLãã ã¬ã¬ã·ãŒã®è¿ä»£å åæã¯ãããèšèªéã®ãªãœãŒã¹ãããŒã«ãŸã§æ¡åŒµããŸããã€ãŸããã¡ã€ã³ãã¬ãŒã ããã°ã©ã ã§ååŸããããªãœãŒã¹ãããªãªãŒã¹ãã¹ãä¿èšŒãããŠããªãJavaãµãŒãã¹ã§æ¶è²»ãããå ŽæããŸãã¯COBOLããã°ã©ã ã§éãããããŒã¿ããŒã¹æ¥ç¶ãJCLãžã§ãã¹ããªãŒã ãçµäºããåã«éããããªãå Žæãç¹å®ããŸãã
ã»ãšãã©ã®èšæ¶æŒããé²ããã£ãäžã€ã®ç¿æ £
ã©ã®èšèªãã©ã®ãã¬ãŒã ã¯ãŒã¯ãã©ã®ã©ã³ã¿ã€ã ã«ãç¬èªã®ã¡ã¢ãªç®¡çã¡ã«ããºã ããããŸãããããããã¹ãŠã«å ±éããæã广çãªç¿æ £ã¯ãã äžã€ããªãœãŒã¹ãäœæããç¬éã«ãã®ææè ãæ±ºå®ããã³ãŒãå ã§ãã®æææš©ãæç€ºçã«ããããšã§ããæææš©ã¯è²¬ä»»ãæå³ããŸããããŒãå²ãåœãŠã®ææè ã¯ãããè§£æŸããããŒã¿ããŒã¹æ¥ç¶ã®ææè ã¯ãããéããã€ãã³ããªã¹ããŒã®ææè ã¯ãããåé€ããŸããæææš©ãæç¢ºã§ããã°ãã¯ãªãŒã³ã¢ããã¯å®¹æã§ããæææš©ãææ§ã§ããã°ãã¯ãªãŒã³ã¢ããã¯åŸåãã«ãããåŸåãã«ãããã¯ãªãŒã³ã¢ãããããã¡ã¢ãªãªãŒã¯ã®åå ãšãªããŸãã
ã¡ã¢ãªãªãŒã¯ãé²ãã³ãŒããã¿ãŒã³ã¯ããã®ååããçŽæ¥å°ãåºããããC++ã®RAIIïŒReturn-Assessed InterpretationïŒã§ã¯ãæææš©ãã¹ã¿ãã¯ãªããžã§ã¯ãã«ç§»è»¢ãããã®ãã¹ãã©ã¯ã¿ãèªåçã«ã¯ãªãŒã³ã¢ããåŠçãè¡ãã try-with-resources Javaãš with Pythonã®ã¹ããŒãã¡ã³ãã¯ããªãœãŒã¹ã®æææš©ã®ç¯å²ãæ§æçã«å¯èŠåããŸããC++ã®ã¹ããŒããã€ã³ã¿ã¯ãæææš©ãè²æž¡ããã³å
±æå¯èœã«ããæåŸã®ææè
ãçµäºãããšãã«ç¢ºå®ã«ã¯ãªãŒã³ã¢ãããããããã«ããŸãããã£ã¢ããŠã³ã¡ãœããã§ã®ç»é²è§£é€ã¯ããªã¹ããŒãšçºè¡è
ã®é¢ä¿ã®ã©ã€ããµã€ã¯ã«ãæç¢ºãã€éå®çãªãã®ã«ããŸãããããã®ãã¿ãŒã³ã¯ãã¹ãŠãæ¬è³ªçã«æææš©ãå¯èŠåãã匷å¶ãèªååããæ¹æ³ã§ãã
æææš©ãæç¢ºã«ããã®ãšå¯Ÿããªãã®ããæç¢ºãªãã¹ãã§ããã¡ã¢ãªãªãŒã¯ã¯ãæ»ãå€ã®ã¿ããã§ãã¯ããæ©èœãã¹ãã§ã¯æ€åºã§ããŸãããæ¥ç¶ãéããããããšããªã¹ããŒãåé€ãããããšãã¹ã¬ããããŒã«ã«ãã¯ãªã¢ãããããšããããã¡ãè§£æŸãããããšãªã©ããªãœãŒã¹ã®ç¶æ ããã§ãã¯ãããã¹ããå¿ èŠã§ãããããã®ã¢ãµãŒã·ã§ã³ããã¹ãã¹ã€ãŒãã«è¿œå ããCIã®äžéšãšããŠã¡ã¢ãªãããã¡ã€ã©ãå®è¡ããã¹ããŒãžã³ã°ç°å¢ã§ç¶ç¶çã«å¢å ããããŒããæ¢ç¥ã®åé¡ã§ã¯ãªããã«ãã®å€±æãšããŠæ±ãããšã¯ãã¡ã¢ãªãªãŒã¯ãèç©ããŠæ¬çªç°å¢ã§ã®ã€ã³ã·ãã³ãã«ã€ãªããã®ãé²ãããã®éçšç¿æ £ã§ãã
ã¡ã¢ãªã¯æéã§ããå²ãåœãŠãããŠè§£æŸãããªããã€ãã¯ãã¹ãŠãã·ã¹ãã ã®ä»ã®éšåã§ã¯äœ¿çšã§ããªããã€ãã§ããäœçŸäžãã®ãªã¯ãšã¹ããåŠçãããµãŒããŒãäœæéãå®è¡ãããã²ãŒã ãåèµ·åã¡ã«ããºã ã®ãªãçµã¿èŸŒã¿ããã€ã¹ã§ã¯ããã®å¶çŽã¯çè«äžã®ãã®ã§ã¯ãããŸãããã¡ã¢ãªã®æææš©ããæ£ç¢ºæ§ãšã»ãã¥ãªãã£ã«é©çšãããã®ãšåãèŠåŸã§æ±ãããšããã·ã¹ãã ãæåã®å±éåŸããããŠæåã®å²ãåœãŠãæžããéçºè ãä»ã®äœæ¥ã«ç§»ã£ãåŸããé·æéå®å®ãããç§èš£ã§ããäœçŸäžãã®ãªã¯ãšã¹ããåŠçãããµãŒããŒãäœæéãå®è¡ãããã²ãŒã ãåèµ·åã¡ã«ããºã ã®ãªãçµã¿èŸŒã¿ããã€ã¹ã§ã¯ããã®å¶çŽã¯çè«äžã®ãã®ã§ã¯ãããŸãããã¡ã¢ãªã®æææš©ããæ£ç¢ºæ§ãšã»ãã¥ãªãã£ã«é©çšãããã®ãšåãèŠåŸã§æ±ãããšããã·ã¹ãã ãæåã®å±éåŸããããŠæåã®å²ãåœãŠãæžããéçºè ãä»ã®äœæ¥ã«ç§»ã£ãåŸããé·æéå®å®ãããç§èš£ã§ãã