From acc
Detects memory issues in PHP code including large arrays, missing generators, memory leaks, unbounded data loading, and inefficient data structures. Useful for OOM errors and high memory usage.
How this skill is triggered — by the user, by Claude, or both
Slash command
/acc:detect-memory-issuesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Analyze PHP code for memory usage problems.
Analyze PHP code for memory usage problems.
// MEMORY HOG: Loading entire table
$users = $repository->findAll(); // 1M users = OOM
foreach ($users as $user) {
process($user);
}
// MEMORY HOG: Building large array
$data = [];
foreach ($hugeDataset as $item) {
$data[] = transform($item); // Array grows unbounded
}
// FIXED: Use generator
function processUsers(Repository $repo): Generator {
foreach ($repo->iterate() as $user) {
yield transform($user);
}
}
// MEMORY HOG: Entire file in memory
$lines = file('large-file.txt'); // 1GB file = OOM
foreach ($lines as $line) {
process($line);
}
// FIXED: Generator-based reading
function readLines(string $path): Generator {
$handle = fopen($path, 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
fclose($handle);
}
// MEMORY HOG: Collect then process
function getAllProducts(): array {
$products = [];
foreach ($this->fetchBatch() as $batch) {
$products = array_merge($products, $batch);
}
return $products; // Entire dataset
}
// MEMORY HOG: No LIMIT
$logs = $repository->findBy(['level' => 'error']);
// Could be millions of records
// MEMORY HOG: Pagination loading all
$page = 1;
$allItems = [];
do {
$items = $api->fetch($page++);
$allItems = array_merge($allItems, $items);
} while (!empty($items));
// FIXED: Process in batches
$page = 1;
do {
$items = $api->fetch($page++);
foreach ($items as $item) {
yield $item;
}
} while (!empty($items));
// MEMORY HOG: Deep object graph
$department = $repo->find($id);
$employees = $department->getEmployees(); // Loads all
foreach ($employees as $emp) {
$projects = $emp->getProjects(); // Loads more
foreach ($projects as $project) {
$tasks = $project->getTasks(); // Even more
}
}
// Entire object graph in memory
// MEMORY HOG: String grows each iteration
$output = '';
foreach ($lines as $line) {
$output .= $line . "\n"; // Creates new string each time
}
// FIXED: Use array and implode
$parts = [];
foreach ($lines as $line) {
$parts[] = $line;
}
$output = implode("\n", $parts);
// BETTER: Use stream
$handle = fopen('output.txt', 'w');
foreach ($lines as $line) {
fwrite($handle, $line . "\n");
}
// MEMORY HOG: Entire image in memory
$image = file_get_contents('large-image.jpg');
$processed = processImage($image);
file_put_contents('output.jpg', $processed);
// MEMORY HOG: Multiple image resources
foreach ($images as $path) {
$img = imagecreatefromjpeg($path);
$resized = imagescale($img, 100, 100);
imagejpeg($resized, $outPath);
// Missing: imagedestroy($img); imagedestroy($resized);
}
// MEMORY LEAK: Cache grows unbounded
class Cache {
private array $data = [];
public function get(string $key): mixed {
if (!isset($this->data[$key])) {
$this->data[$key] = $this->load($key);
// Never evicted
}
return $this->data[$key];
}
}
// MEMORY LEAK: Event listeners accumulate
$dispatcher->addListener('event', function() {
// New closure each time
});
// MEMORY HOG: Doctrine identity map
foreach ($repository->findAll() as $entity) {
$entity->process();
$em->flush(); // Identity map keeps all entities
}
// FIXED: Clear periodically
$batchSize = 100;
$i = 0;
foreach ($repository->iterate() as $entity) {
$entity->process();
if (++$i % $batchSize === 0) {
$em->flush();
$em->clear(); // Free memory
}
}
$em->flush();
// MEMORY HOG: Large session data
$_SESSION['search_results'] = $hugeArray;
// MEMORY HOG: Static cache
class Service {
private static array $cache = [];
public static function process($item) {
self::$cache[$item->getId()] = $item;
// Never cleared
}
}
# file() usage
Grep: "file\([^)]+\)" --glob "**/*.php"
# findAll without iterate
Grep: "->findAll\(\)" --glob "**/*.php"
# array_merge in loop
Grep: "foreach.*array_merge" --glob "**/*.php"
# String concatenation in loop
Grep: 'foreach.*\.=' --glob "**/*.php"
# Static array properties
Grep: "private static array" --glob "**/*.php"
| Operation | Memory Usage |
|---|---|
| 1M integers in array | ~32 MB |
| 1M strings (avg 50 chars) | ~250 MB |
| 1M Doctrine entities | ~500 MB - 2 GB |
| 1 GB file via file() | ~1 GB + overhead |
| Pattern | Severity |
|---|---|
| Unbounded data loading | 🔴 Critical |
| Full table in memory | 🔴 Critical |
| Missing imagedestroy | 🟠 Major |
| Static cache without limit | 🟠 Major |
| String concat in loop | 🟡 Minor |
### Memory Issue: [Description]
**Severity:** 🔴/🟠/🟡
**Location:** `file.php:line`
**Estimated Memory:** ~500 MB for 100K records
**Issue:**
[Description of the memory problem]
**Code:**
```php
// Memory-intensive code
Fix:
// Memory-efficient alternative
Memory Reduction: Before: ~500 MB peak After: ~10 MB peak (streaming)
## When This Is Acceptable
- **CLI commands/workers** — Console commands may legitimately use more memory for batch processing
- **Known bounded datasets** — Loading all items when the table is guaranteed small (e.g., countries, currencies)
- **Cached data** — Large arrays that are built once and cached for reuse
### False Positive Indicators
- Code is in a console command or queue worker with explicit memory management
- Collection is loaded from a known-small dataset (< 1000 records by business rule)
- Large array is built for cache warming with explicit garbage collection
npx claudepluginhub dykyi-roman/awesome-claude-code --plugin accAnalyzes PHP code for lazy loading issues. Detects premature loading, missing pagination, inappropriate eager loading, infinite scroll problems.
Detects memory leaks in Node.js, Python, and JVM apps by analyzing event listeners, closures, unbounded caches, and retained references. Use for troubleshooting memory growth.
Detects N+1 query patterns in custom WordPress theme/plugin PHP code using High/Medium/Low confidence tiers. Skips third-party plugins and provides rewrite suggestions with extracted variable names.