jobjectpool
JObjectPool thread-safe object pooling for Unity. Triggers on: object pool, GC optimization, reusable instances, bullet pool, enemy pool, effect pool, spawn pool, reduce garbage collection, memory optimization, pool prewarm, Rent Return pattern, lock-free pool
Install
mkdir -p .claude/skills/jobjectpool && curl -L -o skill.zip "https://mcp.directory/api/skills/download/3344" && unzip -o skill.zip -d .claude/skills/jobjectpool && rm skill.zipInstalls to .claude/skills/jobjectpool
About this skill
JObjectPool - Thread-Safe Object Pooling
Thread-safe, lock-free generic object pooling for Unity using CAS operations. Works with job system and async operations.
When to Use
- Frequently instantiated objects (bullets, enemies, effects)
- Reducing GC during gameplay
- Multi-threaded object reuse (safe from any thread)
- High-frequency object lifecycle operations
Core API
Constructor
new JObjectPool<T>(
int maxSize = 64, // Maximum pooled objects (excess discarded)
Action<T> onRent = null, // Called when renting (for initialization)
Action<T> onReturn = null // Called when returning (for cleanup)
)
Note: T must be a reference type with a parameterless constructor (where T : class, new()).
Methods
.Rent()- Get object from pool or create new.Return(T obj)- Return object to pool (null values ignored).Clear()- Remove all pooled objects.Prewarm(int count)- Pre-allocate objects (won't exceed maxSize).Count- Current available count (approximate, thread-safe)
Static Access
JObjectPool.Shared<T>()- Global shared pool per type (default config: maxSize=64)
Patterns
Basic Pool
var pool = new JObjectPool<Bullet>(maxSize: 100);
var bullet = pool.Rent();
// ... use bullet ...
pool.Return(bullet);
With Initialization on Rent
var pool = new JObjectPool<Enemy>(
maxSize: 50,
onRent: static enemy => enemy.Reset()
);
Reset State on Return (RECOMMENDED)
var pool = new JObjectPool<List<int>>(
maxSize: 32,
onReturn: static list => list.Clear()
);
Prewarm During Loading
var pool = new JObjectPool<Effect>();
pool.Prewarm(50); // Pre-create during loading screen
Shared Pool (Simple Objects)
// Good for simple reusable objects without custom callbacks
var sb = JObjectPool.Shared<StringBuilder>().Rent();
sb.Append("Hello");
sb.Clear(); // Clean up before returning
JObjectPool.Shared<StringBuilder>().Return(sb);
Game Patterns (Zero-GC)
Bullet Pool with Struct Config
public sealed class Bullet
{
public Vector3 Position;
public Vector3 Velocity;
public float Damage;
public float Lifetime;
public void Reset()
{
Position = default;
Velocity = default;
Damage = 0;
Lifetime = 0;
}
}
public sealed class BulletManager
{
private readonly JObjectPool<Bullet> _pool = new(
maxSize: 200,
onReturn: static b => b.Reset());
public void Initialize() => _pool.Prewarm(100);
public Bullet Fire(in Vector3 pos, in Vector3 dir, float speed, float damage)
{
var bullet = _pool.Rent();
bullet.Position = pos;
bullet.Velocity = dir * speed;
bullet.Damage = damage;
return bullet;
}
public void Return(Bullet b) => _pool.Return(b);
}
Enemy Spawner (Zero-GC State)
public sealed class Enemy : IPoolable
{
public float Health { get; set; }
public Vector3 Position { get; set; }
public event Action OnDeath;
public void OnSpawn()
{
Health = 100f;
}
public void OnDespawn()
{
OnDeath = null; // Clear delegates to prevent leaks
}
}
public sealed class EnemySpawner
{
private readonly JObjectPool<Enemy> _pool;
public EnemySpawner(int maxSize = 50)
{
_pool = new(
maxSize,
onRent: static e => e.OnSpawn(),
onReturn: static e => e.OnDespawn());
}
public Enemy Spawn(in Vector3 position)
{
var enemy = _pool.Rent();
enemy.Position = position;
return enemy;
}
public void Despawn(Enemy e) => _pool.Return(e);
}
Temporary Collection (Zero-GC in Update)
// Use in hot paths to avoid List<T> allocations
public void ProcessNearbyEnemies(in Vector3 center, float radius)
{
var list = JObjectPool.Shared<List<Enemy>>().Rent();
try
{
FindEnemiesNonAlloc(center, radius, list);
foreach (var enemy in list)
{
ProcessEnemy(enemy);
}
}
finally
{
list.Clear();
JObjectPool.Shared<List<Enemy>>().Return(list);
}
}
StringBuilder Pool (Zero-GC String Building)
public static string FormatDamage(float damage, string targetName)
{
var sb = JObjectPool.Shared<StringBuilder>().Rent();
try
{
sb.Append(targetName);
sb.Append(" took ");
sb.Append(damage.ToString("F1"));
sb.Append(" damage");
return sb.ToString();
}
finally
{
sb.Clear();
JObjectPool.Shared<StringBuilder>().Return(sb);
}
}
Best Practices
- Pre-allocate during loading to prevent in-game allocation spikes
- Reset state on return to prevent data leaks between reuses
- Set appropriate maxSize based on expected concurrent usage
- Use shared pools for simple objects without custom callbacks
- Monitor pool Count to optimize sizing
Troubleshooting
Objects Not Reused
- Forgot to Return: Always call
pool.Return(obj)when done - Pool at capacity: Increase maxSize if concurrent usage exceeds limit
- Returning null: Null values are silently ignored
Stale Data / Memory Leaks
- Not resetting state: Clear all fields in onReturn callback
- Event delegates: Unsubscribe all events in onReturn to prevent leaks
- References to disposed objects: Null out references in onReturn
Performance Issues
- Not pre-warming: Call
Prewarm()during loading screens - maxSize too low: Causes allocations when pool empties
- maxSize too high: Wastes memory
Thread Safety
- JObjectPool IS thread-safe (lock-free CAS)
- Safe to Rent/Return from any thread
- onRent/onReturn run on calling thread
Common Mistakes
- Returning null to pool (ignored, but wasteful)
- Not clearing object state on return (causes bugs from stale data)
- Forgetting to return objects (pool becomes ineffective)
- Setting maxSize too low (causes frequent allocations)
- Setting maxSize too high (wastes memory)
More by JasonXuDeveloper
View all skills by JasonXuDeveloper →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversEmpower your Unity projects with Unity-MCP: AI-driven control, seamless integration, and advanced workflows within the U
Connect Blender to Claude AI for seamless 3D modeling. Use AI 3D model generator tools for faster, intuitive, interactiv
MCP Toolbox for Databases by Google. An open-source server that lets AI agents query Cloud SQL, Spanner, AlloyDB, and ot
JsonDiffPatch: compare and patch JSON with a compact delta format capturing additions, edits, deletions, and array moves
Create modern React UI components instantly with Magic AI Agent. Integrates with top IDEs for fast, stunning design and
AI-driven CAD modeling with FreeCAD: control design workflows, generate logos, and edit objects using remote Python scri
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.