Heavy Object Pooling Frame Drops, HELP!

Hi, i have been working on a bullet-hell game for a bit. I, recently have been having a huge problem with frame drops when pooling bullets in my game. Each bullet is enabled with a rigidbody2d and a circle collider upon shooting a bullet, which results in around a 15 frame drop per bullet. When looking at the profiler, it says it is GC.Alloc does anyone know how I can prevent this? I provided a photo of the profiler, as well as the main bullet script I use.

using System.Collections;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float damage;
    public bool rocketLanded;
    public Vector3 direction;
    public GameObject hitmarkerPrefab;
    public GameObject bigShotDustExplosionPrefab;
    public GameObject nanoBugPrefab;
    public GameObject bulletContactObjectParticle;
    public GameObject bulletContactEnemyParticle;
    public GameObject bloodyPop;
    public GameObject zodenExplodeParticles;
    public GameObject palmOfZoden;

    public bool PalmOfZodenActive;
    private bool canCheckCollision = true;
    private TrailRenderer trailRenderer;

    private Player player;
    private PlayerProjectiles playerProjectiles;

    [SerializeField] private AudioClip[] fleshImpactSoundFX;

    private void Awake()
    {
        player = FindObjectOfType<Player>();
        playerProjectiles = FindObjectOfType<PlayerProjectiles>();
        trailRenderer = GetComponent<TrailRenderer>();
    }

    private void OnEnable()
    {
        Ticker.OnTickAction += AllowCollisionCheck;
        PalmOfZodenActive = false;
        StartCoroutine(SetTrailRenderer());
    }

    private void OnDisable()
    {
        Ticker.OnTickAction -= AllowCollisionCheck;
    }

    private void AllowCollisionCheck()
    {
        canCheckCollision = true;
    }

    private IEnumerator SetTrailRenderer()
    {
        trailRenderer.time = 0;
        yield return new WaitForSeconds(0.17f);
        trailRenderer.time = 0.2f;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (!canCheckCollision) return;

        if (IsIgnoredTag(collision.tag))
        {
            Physics2D.IgnoreCollision(collision, GetComponent<Collider2D>());
            return;
        }

        if (collision.CompareTag("Enemy"))
        {
            HandleEnemyCollision(collision);
        }
        else if (collision.CompareTag("Object"))
        {
            HandleObjectCollision();
        }
    }

    private void HandleEnemyCollision(Collider2D collision)
    {
        if (player.playerHasInfestedCasings && Random.value >= 0.5f)
        {
            ObjectPoolManager.SpawnObject(nanoBugPrefab, transform.position, Quaternion.identity);
        }

        EnemyRecieveDamage enemyDamage = collision.GetComponent<EnemyRecieveDamage>();
        if (player.playerHasMetamorphasis && Random.value >= 0.9f)
        {
            enemyDamage?.Metamorphasis();
        }

        if (player.playerHasGlassCasings)
        {
            enemyDamage?.GlassCasings();
        }

        if (player.playerHasPalmOfZoden && PalmOfZodenActive)
        {
            ObjectPoolManager.SpawnObject(palmOfZoden, collision.transform.position, Quaternion.identity);
        }

        if (player.playerHasSkullOfZoden && Random.Range(0, 4) <= player.playerLuck)
        {
            collision.GetComponent<StatusEffect>()?.InflictFleshRot();
        }

        if (player.playerHasBeefyBullets)
        {
            ApplyKnockback(collision);
        }

        enemyDamage?.DealDamage(damage);
        PlayFleshImpactSound();

        if (player.playerHasComboShot)
        {
            playerProjectiles.comboShot += 0.2f;
        }

        SpawnBulletImpactEffect(bulletContactEnemyParticle, bloodyPop);
        HandleExplosionIfApplicable();

        if (!player.playerHasFMJ)
        {
            ReturnBulletToPool();
        }
    }

    private void HandleObjectCollision()
    {
        SpawnBulletImpactEffect(bulletContactObjectParticle, null);
        HandleExplosionIfApplicable();

        if (player.playerHasComboShot)
        {
            playerProjectiles.comboShot = 0f;
        }

        ReturnBulletToPool();
    }

    private void ApplyKnockback(Collider2D collision)
    {
        Rigidbody2D rb = collision.GetComponent<Rigidbody2D>();
        if (rb != null)
        {
            Vector2 knockbackDirection = -(collision.transform.position - transform.position).normalized;
            rb.AddForce(knockbackDirection * 10f, ForceMode2D.Impulse);
        }
    }

    private void SpawnBulletImpactEffect(GameObject particlePrefab, GameObject secondaryEffect)
    {
        if (particlePrefab != null)
        {
            Rigidbody2D rb = GetComponent<Rigidbody2D>();
            if (rb != null)
            {
                Vector3 bulletDirection = rb.velocity.normalized;
                Vector3 spawnPosition = transform.position + bulletDirection * 0.2f;
                float angle = Mathf.Atan2(bulletDirection.y, bulletDirection.x) * Mathf.Rad2Deg;
                Quaternion rotation = Quaternion.Euler(0, 0, angle);

                ObjectPoolManager.SpawnObject(particlePrefab, spawnPosition, rotation);

                if (secondaryEffect != null)
                {
                    ObjectPoolManager.SpawnObject(secondaryEffect, spawnPosition, rotation);
                }
            }
        }
    }

    private void PlayFleshImpactSound()
    {
        SoundFXManager.instance.PlayRandomSoundFXClip(fleshImpactSoundFX, transform, 1f);
    }

    public void ReturnBulletToPool()
    {
        ObjectPoolManager.ReturnObjectToPool(gameObject);
    }

    public void HandleExplosionIfApplicable()
    {
        if (player.playerHasRocketLauncher || player.playerHasCombustionCanister || player.playerHasPredatorMissle || player.playerHasSkullOfZoden)
        {
            ObjectPoolManager.SpawnObject(bigShotDustExplosionPrefab, transform.position, Quaternion.identity);

            if (player.playerHasSkullOfZoden)
            {
                ObjectPoolManager.SpawnObject(zodenExplodeParticles, transform.position, Quaternion.identity);
            }

            RaycastHit2D[] hits = Physics2D.CircleCastAll(transform.position, playerProjectiles.explosionRadius, Vector2.zero);
            foreach (RaycastHit2D hit in hits)
            {
                if (hit.collider.CompareTag("Enemy"))
                {
                    hit.collider.GetComponent<EnemyRecieveDamage>()?.DealDamage(playerProjectiles.damage / 2);
                }
                else if (hit.collider.CompareTag("Player") && !player.playerHasPHD)
                {
                    hit.collider.GetComponent<PlayerReceiveDamage>()?.DealDamage(1);
                }
            }
        }
    }

    private bool IsIgnoredTag(string tag)
    {
        return tag == "Player" || tag == "Familiar" || tag == "Deflector" || tag == "Water" || tag == "Ground" ||
               tag == "Fish" || tag == "Boat" || tag == "FishWater" || tag == "Blood" || tag == "PlayerProjectile";
    }
}
![FrameDrop|690x367](upload://qfZ31PE6g1bju2brdnkQ842bd6P.jpeg)

Pooling is not a magic sauce. It can certainly cause slowdowns if you didn’t need it in the first place. Did you determine that it was necessary before implementing pooling?

The costs and issues associated with object pooling / pools:

In very rare extremely-high-count object circumstances I have seen small benefits from pooling.

In MOST circumstances, object pooling is a source of complexity, bugs and edge cases while not giving any measurable benefit.