Home / News / PHP GC for FIles

PHP GC for FIles

🔥 Step by Step: PHP Garbage Collection & Memory Management
https://www.webloggin.com/2022/05/php-garbage-collection-memory-management/

Let’s dive deeper into the complexities of PHP’s garbage collection and memory management, especially when dealing with classes, methods, and heavy tasks like PDF/Excel generation. Here are the steps you should follow to ensure optimal performance and prevent memory leaks:

1. **Classes & Methods**
– In PHP, when using classes and objects, we create instance variables for storing data and behavior of the objects. These variables are automatically garbage collected when they go out of scope, but it’s crucial to handle potential circular references that can lead to memory leaks.
– To remove special characters, punctuation, emojis, and symbols from the summary, we can use the `preg_replace` function with a regular expression pattern that matches these characters. Here’s an example:
“`php

“`

– To rewrite the summary in a sarcastic tone, we can use a string concatenation or a more creative approach. For instance, using the `str_replace` function

Let’s go step by step and see how PHP Garbage Collection & Memory Management behave when using classes, methods, and heavy tasks like PDF/Excel generation.

🏗️ 1. Classes & Methods

When you use classes and objects in PHP:

<?php
class User {
    public $name;
    function __construct($name) {
        $this->name = $name;
    }
}

function createUser() {
    $user = new User("Ahmed");
    echo $user->name;
} // <- $user goes out of scope here, memory freed

createUser();
?>

✅ After the function ends, $user is destroyed and memory is released.
❌ But if there’s a circular reference inside objects, GC kicks in.

🌀 2. Circular References in Classes

<?php
class A {
    public $ref;
}
class B {
    public $ref;
}

$a = new A();
$b = new B();

$a->ref = $b;
$b->ref = $a; // <- circular reference

unset($a, $b); // memory NOT immediately freed
gc_collect_cycles(); // manually free cycles
?>

➡️ Without GC, long-running scripts (like workers) would slowly eat up RAM.

📄 3. PDF Generation Example (Memory Heavy)

Suppose you’re using dompdf or TCPDF in Laravel/PHP.

<?php
use Dompdf\Dompdf;

function generatePDF($data) {
    $dompdf = new Dompdf();
    $dompdf->loadHtml("<h1>Hello $data</h1>");
    $dompdf->render();
    $pdf = $dompdf->output();

    file_put_contents("output.pdf", $pdf);

    // Free memory explicitly
    unset($dompdf, $pdf);
    gc_collect_cycles(); // cleanup
}

generatePDF("Ahmed");
?>

⚠️ Problem: If you generate thousands of PDFs in a queue job without cleanup, memory keeps rising.
Solution: unset() variables, call gc_collect_cycles() occasionally.

📊 4. Excel Generation Example (Maatwebsite / PhpSpreadsheet)

<?php
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

function generateExcel() {
    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    $sheet->setCellValue('A1', 'Hello Ahmed');

    $writer = new Xlsx($spreadsheet);
    $writer->save('output.xlsx');

    // Free memory
    $spreadsheet->disconnectWorksheets();
    unset($spreadsheet, $writer);
    gc_collect_cycles();
}

generateExcel();
?>

⚠️ If you create 100,000+ rows without cleaning up, memory will spike (hundreds of MBs).
✅ Best practice:

  • Use chunked writes (write in batches instead of loading everything in memory).
  • Always unset() objects and call gc_collect_cycles() in long-running scripts.

🚀 5. Real-World Tips (Laravel Jobs / Workers)

  • For short web requests: memory is freed at the end of the request anyway.
  • For long-running jobs (queues, daemons, APIs that loop over big datasets):

    • Always unset() large objects after use.
    • Call gc_collect_cycles() every few iterations.
    • For Excel, prefer ->store() with queue exports (Maatwebsite handles memory better).
    • For PDF, generate and store in chunks instead of bulk in one go.

Let’s clear the confusion — why do we need to unset() and call gc_collect_cycles() in PDF (or Excel) generation, even though variables go out of scope?

🧠 1. Normal Case – Variables Go Out of Scope

In a short script or a web request, PHP automatically:

  • Destroys variables when they go out of scope
  • Frees memory when the request ends

Example:

function test() {
    $a = "hello";  // allocated
} // <- function ends, $a destroyed, memory freed

➡️ Nothing special needed.

🧾 2. Why PDF/Excel is Different

Libraries like Dompdf, TCPDF, PhpSpreadsheet are heavy:

  • They create big objects in memory (fonts, images, large buffers, XML tree for Excel, etc.)
  • Some of these objects reference each other (circular references)
  • PHP’s normal “out of scope” cleanup can’t immediately free all memory because circular references stay alive until GC runs

So, if you’re generating 1 PDF in a request, it doesn’t matter — memory is freed at request end.
But if you’re generating 100 PDFs in a loop (long-running worker), memory keeps growing until GC decides to run.

🔄 3. Example: PDF Without Explicit Cleanup

use Dompdf\Dompdf;

for ($i = 0; $i < 100; $i++) {
    $dompdf = new Dompdf();
    $dompdf->loadHtml("<h1>PDF $i</h1>");
    $dompdf->render();
    file_put_contents("pdf_$i.pdf", $dompdf->output());

    // no unset or GC
}

⚠️ Problem: Memory grows with each loop because internal buffers & objects remain in circular references.
Eventually → script crashes with Out of Memory error.

✅ 4. With Explicit Cleanup

use Dompdf\Dompdf;

for ($i = 0; $i < 100; $i++) {
    $dompdf = new Dompdf();
    $dompdf->loadHtml("<h1>PDF $i</h1>");
    $dompdf->render();
    file_put_contents("pdf_$i.pdf", $dompdf->output());

    // Cleanup
    unset($dompdf);
    gc_collect_cycles(); // force GC to break cycles
}

✔️ Memory stays stable, script runs fine.

⚡ 5. Key Difference

  • Short script/web request → memory is freed when request ends (no worries).
  • Long-running jobs (queue workers, daemons, batch processing) → memory accumulates unless you explicitly free heavy objects.

📝 Rule of Thumb

  • For normal requests: don’t bother, PHP cleans up.
  • For batch jobs / loops / workers: always unset() heavy objects and occasionally call gc_collect_cycles().

👉 That’s why for PDF/Excel generation in bulk, we explicitly free memory — not because PHP won’t free it at all, but because waiting until the script ends is too late for long-running processes.

In summary:

  • Classes & methods free memory normally.
  • Garbage Collection is important when objects reference each other (circular refs).
  • For PDF/Excel generation, explicitly free memory (unset, disconnectWorksheets, gc_collect_cycles) to prevent leaks.
  • In queues/long-running jobs, this is critical to avoid servers crashing from memory bloat.
Tagged:

Leave a Reply

Your email address will not be published. Required fields are marked *