bhylu.com

Advertisements

AI TensorFlow.js Memory

Release temporary tensors across repeated calculations.

How it works

TensorFlow.js tensor storage is not managed solely by JavaScript garbage collection. tf.tidy can release temporary synchronous tensors, while returned tensors remain the caller’s responsibility. Async operations need explicit ownership. This lab repeats a calculation and compares tensor counts before and after each owned result is disposed.

Run the code

This complete HTML document is a separate learning lab. Download download-labs.mjs into an empty folder and run node download-labs.mjs. For an unpublished local preview use node download-labs.mjs http://127.0.0.1:8000/examples/ai/. It saves hash-checked sources, pinned vendor assets and licence notices into a new bhylu-ai-lab folder and refuses an existing destination. Review the files, enter that folder, run node serve.mjs and open http://127.0.0.1:8138/tensorflow-memory.html. Select Run explicitly. The server is read-only, binds loopback and stops with Ctrl+C. It changes no PHP, Apache or database settings.

The reviewed browser baselines are TensorFlow.js 4.22.0, tfjs-vis 1.5.1, Brain.js 2.0.0-beta.24 (prerelease), Chart.js 4.5.1, D3 7.9.0 and Plotly.js 3.1.0. Only the libraries listed by this document load into the separate learning page. The plain JavaScript/Python playground does not supply them. TensorFlow.js labs select the CPU backend; no GPU support or speed claim follows.

Download the complete tensorflow-memory.html

Example

tensorflow-memory.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Bhylu AI - TensorFlow.js Memory</title>
    <style>
      body {
        font: 16px/1.6 system-ui;
        max-width: 760px;
        margin: 32px auto;
        padding: 0 20px;
        color: #0f3464;
        background: #fff;
      }
      button {
        font: inherit;
        padding: 8px 20px;
        background: #0078d4;
        color: white;
        border: 0;
        border-radius: 6px;
      }
      pre {
        white-space: pre-wrap;
        overflow-wrap: anywhere;
        background: #f3f7fc;
        padding: 16px;
      }
      canvas,
      svg,
      #chart {
        max-width: 100%;
      }
    </style>
  </head>
  <body>
    <h1>TensorFlow.js Memory</h1>
    <p>Release temporary tensors across repeated calculations.</p>
    <p>
      This separate synthetic-data lab runs only when you select Run. It is not a model
      service or a production benchmark.
    </p>
    <button id="run" type="button">Run example</button>
    <pre id="output" aria-live="polite"></pre>
    <script src="vendor/tf.min.js"></script>
    <script>
      const runButton = document.getElementById("run");
      const output = document.getElementById("output");
      const print = (value) => {
        output.textContent += String(value) + "\n";
      };
      window.aiDone = false;
      window.aiFailure = null;
      runButton.addEventListener("click", async () => {
        runButton.disabled = true;
        output.textContent = "";
        window.aiDone = false;
        window.aiFailure = null;
        try {
          await tf.setBackend("cpu");
          await tf.ready();
          const before = tf.memory().numTensors;
          for (let i = 0; i < 20; i++) {
            const result = tf.tidy(() =>
              tf
                .tensor1d([i, i + 1])
                .square()
                .sum(),
            );
            await result.data();
            result.dispose();
          }
          print("tensor count restored: " + (tf.memory().numTensors === before));
        } catch (error) {
          window.aiFailure = String(error);
          print("Error: " + error.message);
        } finally {
          window.aiDone = true;
          runButton.disabled = false;
        }
      });
    </script>
  </body>
</html>

Focus on the JavaScript operations

This excerpt omits document markup, local library loading and the explicit Run control. Use the full source to run it.

Operation excerpt

const before = tf.memory().numTensors;
for(let i=0;i<20;i++) {
  const result = tf.tidy(()=>tf.tensor1d([i, i+1]).square().sum());
  await result.data();
  result.dispose();
}
print('tensor count restored: ' + (tf.memory().numTensors === before));

Expected result

tensor count restored: true

The count concerns library tensor objects in this reviewed CPU experiment. It does not prove total browser memory usage, GPU allocation behaviour or absence of every leak. Repeating Run is also checked so retained state does not quietly accumulate.

Technical references