Skip to content

fix: memory leaks in Item wrappers and optimize CustomItems#763

Open
MS-crew wants to merge 11 commits intoExMod-Team:devfrom
MS-crew:MemoryLeakF
Open

fix: memory leaks in Item wrappers and optimize CustomItems#763
MS-crew wants to merge 11 commits intoExMod-Team:devfrom
MS-crew:MemoryLeakF

Conversation

@MS-crew
Copy link

@MS-crew MS-crew commented Feb 28, 2026

Description

Updated Item.Destroy so if an item isnt actually in an inventory it properly removes it from the dict and forces gameobject destroy so the leak is completely gone.

CustomGrenade.Throw was throwing nres when player was null cause server host doesnt have a camera or fpc role. also it was spawning a whole dummy item just to throw it which is bad for perf so i rewrote it to just use native throwable templates.

CustomWeapon.Spawn was leaving the temporary firearm in memory after creating the pickup. added a destroy call for that.

Fixed genericfirearm damage handler cause ragdolls were only showing bullet wounds and when dying attacker is null from client side. it reads the ammo type directly from the native template module now.

GenerateAttachments was literally spawning every single gun on server startup just to read attachments which is nonsense. changed it to use native templates

fun fact: before this fix, exiled was casually leaving 14 dead firearm objects in memory on server startup before any plugins even did anything. that's completely gone now.

What is the current behavior? (You can also link to an open issue here)

What is the new behavior? (if this is a feature change)

Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)

Other information:


Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentations

Submission checklist

  • I have checked the project can be compiled
  • I have tested my changes and it worked as expected

Patches (if there are any changes related to Harmony patches)

  • I have checked no IL patching errors in the console

Other

  • Still requires more testing

@Someone-193
Copy link

ughhh this is gonna take me forever to read 😭
I do agree though that the Spawn methods can be problematic, you had an issue with that + 1344 iirc. I would like to point out though that Item::Destroy is only necessary for methods that create items, you added Item::Destroy to the spawn overloads that take in an item too, which in theory just breaks behavior because that method should've effectively duplicated the item (by just creating a pickup of it without destroying it). Plugin devs should've then have already accounted for this if they used that overload

@MS-crew MS-crew requested a review from Someone-193 March 5, 2026 22:53
Copy link

@Someone-193 Someone-193 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I think everything here seems fine, but this definitely needs good testing lol. If you could Ms, could you test this PR on your server like how you mentioned you got the stamina problem on a server on dev?

Copy link

@louis1706 louis1706 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only things i am asking other than that it's fine consider approved when the CodeReview is merged

Comment on lines +2332 to +2338
Item item = Item.Create(usableItem);

if (item is not Usable usable)
{
item.Destroy();
return false;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the previous line verify than it's Usable i don't see why we would need to make the check twice ?

Suggested change
Item item = Item.Create(usableItem);
if (item is not Usable usable)
{
item.Destroy();
return false;
}
Item item = Item.Create<Usable>(usableItem);

Comment on lines +74 to 80
Item item = Item.Create(Type);
if (item is not Firearm firearm)
{
Log.Debug($"{nameof(Spawn)}: Item is not Firearm.");
item.Destroy();
return null;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Item item = Item.Create(Type);
if (item is not Firearm firearm)
{
Log.Debug($"{nameof(Spawn)}: Item is not Firearm.");
item.Destroy();
return null;
}
if (Type.IsWeapon(false))
{
Log.Warn($"{nameof(Spawn)}: Item is not Firearm.");
return null;
}
Firearm firearm = Item.Create<Firearm>(Type);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants