[]
DsPdfJS objects are wrappers around underlying C++ objects that run inside the WebAssembly module. Each TypeScript object corresponds to an internal WebAssembly object that performs the actual processing.
Because JavaScript garbage collection does not automatically release these WebAssembly resources, DsPdfJS provides a memory management system that ensures objects are properly tracked and released.
Every DsPdfJS object belongs to an ObjectManager, which defines the lifetime scope of the underlying WebAssembly objects.
The ObjectManager class controls the lifetime of DsPdfJS objects created within its scope.
An instance of ObjectManager maintains a list of active WebAssembly objects. Even if the JavaScript wrapper object is garbage collected, the underlying WebAssembly object remains alive until the owning ObjectManager is disposed or the object is explicitly released.
When an object manager is disposed, all objects associated with it are released and their underlying resources can be destroyed if no other references remain.
You can create an object manager explicitly:
const om = new ObjectManager();
const doc = new PdfDocument(om);
const font = Font.getPdfFont(om, StandardPdfFont.Times);
const img = Image.load(om, imageBytes);
om.dispose();Object managers define the lifetime scope of the objects they contain. Multiple managers can be used for objects with different lifetimes. For example, one manager might hold long‑lived resources such as fonts, while another manages short‑lived objects such as temporary documents or images.
ObjectManager
├─ PdfDocument
├─ Image
├─ Font
└─ BmpContextAll DsPdfJS objects derive from the ObjectBase class. Examples include PdfDocument, Image, Font, Bitmap, Layout, SvgDocument, and many others.
Each ObjectBase instance is associated with an ObjectManager. Important members of ObjectBase include:
om - Returns the ObjectManager responsible for managing the object.
id - Provides an internal reference used to communicate with the WebAssembly layer.
free - Detaches the object from its ObjectManager and deallocates the underlying memory if possible.
rebind(omTo) - Moves the object from its current ObjectManager to another one.
Objects can be released either by calling free free or automatically when the owning ObjectManager is disposed.
You can create and dispose object managers manually to control object lifetimes.
const om = new ObjectManager();
const ctx = new BmpContext(om, 300, 200, 2, "MediumPurple");
ctx.translate(150, 100);
const lgBr = new LinearGradientBrush(om, {
startColor: "Red",
endColor: "LightGreen",
startPoint: { x: 0, y: 0 },
endPoint: { x: 1, y: 1 }
});
ctx.drawRect(-100, -50, 200, 100, {
radius: 10,
fillBrush: lgBr,
lineColor: "White",
lineWidth: 5
});
Util.showBitmap(ctx.bitmap);
om.dispose();In environments that support the using statement, the object manager can also be disposed automatically when leaving the scope.
using om = new ObjectManager();
const ctx = new BmpContext(om, 300, 200, 2, "MediumPurple");Passing an ObjectManager instance to every constructor can become cumbersome. DsPdfJS provides a global object manager stack that allows objects to automatically attach to the currently active manager.
The following helper functions manage the stack:
pushObjectManager – creates and pushes a new object manager onto the stack.
popObjectManager – removes and disposes the manager at the top of the stack.
getCurrentObjectManager – returns the currently active manager.
hasCurrentObjectManager – checks whether a manager exists on the stack.
Example:
pushObjectManager();
const img1 = Image.load(await Util.loadImageAsArray("parrots.jpg"));
ctx.drawImage(img1, 72, 72, img1.width / 2.5, img1.height / 2.5);
const img2 = Image.load(await Util.loadImageAsArray("top-secret.png"));
ctx.drawImage(img2, 230, 320, img2.width, img2.height);
const svg1 = SvgDocument.load(await Util.loadImageAsArray("RadGrad.svg"));
ctx.drawSvg(svg1, 330, 130);
// Release all images
popObjectManager();Important: The popObjectManager method must always be called after pushObjectManager. Failing to do so corrupts the object manager stack.
Avoid returning from a function between these calls unless cleanup is handled using try...finally.
DsPdfJS provides the withObjectManager decorator to simplify resource management.
This decorator automatically:
creates and pushes an ObjectManager when the function starts
pops and disposes it when the function finishes
ensures cleanup even if an exception occurs
Example:
@withObjectManager
async svgToPng() {
const svgDoc = SvgDocument.load(await Util.loadImageAsArray("ManReading.svg"));
const rect = svgDoc.measure(0, 0);
const ctx = new BmpContext(rect.width + 0.4, rect.height + 0.4, 1, "Snow");
ctx.slowAntialiasing = true;
ctx.drawSvg(svgDoc, -rect.x, -rect.y);
const pngBytes = ctx.bitmap.saveAsPng();
Util.saveFile("ManReading.png", pngBytes, "image/png");
}Using the decorator is the safest way to ensure object managers are always paired and disposed.
When working with DsPdfJS objects:
Prefer using withObjectManager for automatic scope management.
Ensure every pushObjectManager call is paired with popObjectManager.
Avoid leaving object managers on the stack.
Use separate object managers for objects with different lifetimes.
Use free only when you need to release a specific object before the manager is disposed.