Memory Optimization
Overview
Memory optimization improves application performance, stability, and reduces infrastructure costs. Efficient memory usage is critical for scalability.
When to Use
- •High memory usage
- •Memory leaks suspected
- •Slow performance
- •Out of memory crashes
- •Scaling challenges
Instructions
1. Memory Profiling
javascript
// Browser memory profiling
// Check memory usage
performance.memory: {
jsHeapSizeLimit: 2190000000, // Max available
totalJSHeapSize: 1300000000, // Total allocated
usedJSHeapSize: 950000000 // Currently used
}
// React DevTools Profiler
- Open React DevTools → Profiler
- Record interaction
- See component renders and time
- Identify unnecessary renders
// Chrome DevTools
1. Open DevTools → Memory
2. Take heap snapshot
3. Compare before/after
4. Look for retained objects
5. Check retained sizes
// Node.js profiling
node --inspect app.js
// Open chrome://inspect
// Take heap snapshots
// Compare growth over time
2. Memory Leak Detection
python
# Identify and fix memory leaks
class MemoryLeakDebug:
def identify_leaks(self):
"""Common patterns"""
return {
'circular_references': {
'problem': 'Objects reference each other, prevent GC',
'example': 'parent.child = child; child.parent = parent',
'solution': 'Use weak references or cleaner code'
},
'event_listeners': {
'problem': 'Listeners not removed',
'example': 'element.addEventListener(...) without removeEventListener',
'solution': 'Always remove listeners on cleanup'
},
'timers': {
'problem': 'setInterval/setTimeout not cleared',
'example': 'setInterval(() => {}, 1000) never clearInterval',
'solution': 'Store ID and clear on unmount'
},
'cache_unbounded': {
'problem': 'Cache grows without bounds',
'example': 'cache[key] = value (never deleted)',
'solution': 'Implement TTL or size limits'
},
'dom_references': {
'problem': 'Removed DOM elements still referenced',
'example': 'var x = document.getElementById("removed")',
'solution': 'Clear references after removal'
}
}
def detect_in_browser(self):
"""JavaScript detection"""
return """
// Monitor memory growth
setInterval(() => {
const mem = performance.memory;
const used = mem.usedJSHeapSize / 1000000;
console.log(`Memory: ${used.toFixed(1)} MB`);
}, 1000);
// If grows over time without plateau = leak
"""
3. Optimization Techniques
yaml
Memory Optimization:
Object Pooling:
Pattern: Reuse objects instead of creating new
Example: GameObject pool in games
Benefits: Reduce GC, stable memory
Trade-off: Complexity
Lazy Loading:
Pattern: Load data only when needed
Example: Infinite scroll
Benefits: Lower peak memory
Trade-off: Complexity
Pagination:
Pattern: Process data in chunks
Example: 1M records → 1K per page
Benefits: Constant memory
Trade-off: More requests
Stream Processing:
Pattern: Process one item at a time
Example: fs.createReadStream()
Benefits: Constant memory for large data
Trade-off: Slower if cached
Memoization:
Pattern: Cache expensive calculations
Benefits: Faster, reuse results
Trade-off: Memory for speed
---
Framework-Specific:
React:
- useMemo for expensive calculations
- useCallback to avoid creating functions
- Code splitting / lazy loading
- Windowing for long lists (react-window)
Node.js:
- Stream instead of loadFile
- Limit cluster workers
- Set heap size: --max-old-space-size=4096
- Monitor with clinic.js
---
GC (Garbage Collection):
Minimize:
- Object creation
- Large allocations
- Frequent new objects
- String concatenation
Example (Bad):
let result = "";
for (let i = 0; i < 1000000; i++) {
result += i.toString() + ",";
// Creates new string each iteration
}
Example (Good):
const result = Array.from(
{length: 1000000},
(_, i) => i.toString()
).join(",");
// Single allocation
4. Monitoring & Targets
yaml
Memory Targets: Web App: Initial: <10MB After use: <50MB Peak: <100MB Leak check: Should plateau Node.js API: Per-process: 100-500MB Cluster total: 1-4GB Heap size: Monitor vs available RAM Mobile: Initial: <20MB Working: <50MB Peak: <100MB (device dependent) --- Tools: Browser: - Chrome DevTools Memory - Firefox DevTools Memory - React DevTools Profiler - Redux DevTools Node.js: - node --inspect - clinic.js - nodemon --exec with monitoring - New Relic / DataDog Monitoring: - Application Performance Monitoring (APM) - Prometheus + Grafana - CloudWatch - New Relic --- Checklist: [ ] Profile baseline memory [ ] Identify heavy components [ ] Remove event listeners on cleanup [ ] Clear timers on cleanup [ ] Implement lazy loading [ ] Use pagination for large lists [ ] Monitor memory trends [ ] Set up GC monitoring [ ] Test with production data volume [ ] Stress test for leaks [ ] Establish memory budget [ ] Set up alerts
Key Points
- •Take baseline memory measurements
- •Use profilers to identify issues
- •Remove listeners and timers on cleanup
- •Implement streaming for large data
- •Use lazy loading and pagination
- •Monitor GC pause times
- •Set heap size appropriate for workload
- •Object pooling for frequent allocations
- •Regular memory testing with real data
- •Alert on memory growth trends