Best ways to find memory leak?

I’m not a scripter. How can I locate memory leak in my game? I know that it’s there. It’s hard to not notice it.
It goes up by like 80mb every 10 minutes of playing.

So how can I detect which script causes it? Keep in mind that I’m not a scripter.

1 Like

Press ctrl+shift+f6

Go into modes>Detail

inside of Detailed mode, you want to pause the frames. press the pause button on top
image

in detailed mode, go to your frames, and select a frame that looks high…
image

Now find lines that are long like this:


(but aren’t scene, as scene will always be a long line.)
if scene is logner than usual, aka taking more milliseconds, then that means there coukd be a lot of meshes or something.


I probably explaind that in a bad way, so I’ve made my own script to hopefully cause these spikes
I made a script that prints super fast and so fast it lags the game terribly

as you can see I was able to find it inside the scripts, it lasts almost the whole frame, meaning it causes the lag

so basically you find scripts that use this metho, and for example I have this script

game:GetService("RunService").RenderStepped:Connect(function()
	warn("TestingTestingTesting")
	game:GetService("RunService").RenderStepped:Connect(function()
		warn("TestingTestingTesting")
	end)
end)

and that acuses lag and when I remove it, the micoprofiler doesn’t have spikes and there is no constant “print” display the whole frame

2 Likes

Does checking for an increase in the memory section of Luau heap also indicate something?
A script inside of my game rises up immensely over time in that section. How can I prevent Memory Leak here?
I asked ChatGPT and the result he gave me made it rise up even more

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local Client = ReplicatedStorage:WaitForChild("Client")
local Round = ReplicatedStorage:WaitForChild("Round")
local FullRoundEnd = Round:WaitForChild("FullRoundEnd")
local ReplicateMovingPart = Client:WaitForChild("ReplicateMovingPart")
local ReplicateRotatingPart = Client:WaitForChild("ReplicateRotatingPart")
local ReplicateConveyor = Client:WaitForChild("ReplicateConveyor")
local ConnectDeathPart = Client:WaitForChild("ConnectDeathPart")

local ReplicateMovingParts = {}
local Debris = {}

local function cleanUpConnections()
	for _, connection in pairs(Debris) do
		connection:Disconnect()
	end
	Debris = {}
end

ReplicateMovingPart.OnClientEvent:Connect(function(Object, Info, Props, MovesPlayer)
	local tweeninfo = TweenInfo.new(table.unpack(Info))
	local Tween = TweenService:Create(Object, tweeninfo, Props)
	Tween:Play()

	if MovesPlayer then
		local LastPosition = Object.Position
		local connection
		connection = RunService.RenderStepped:Connect(function(deltaTime)
			if Object and Object.Parent then
				local CurrentPosition = Object.Position
				local deltaPosition = CurrentPosition - LastPosition
				local Velocity = deltaPosition / deltaTime
				Object.AssemblyLinearVelocity = Velocity
				LastPosition = CurrentPosition
			else
				connection:Disconnect()
			end
		end)
		table.insert(Debris, connection)
	end
end)

ReplicateRotatingPart.OnClientEvent:Connect(function(Object, Info, Props, MovesPlayer)
	local tweeninfo = TweenInfo.new(table.unpack(Info))
	local Tween = TweenService:Create(Object, tweeninfo, Props)
	Tween:Play()

	if MovesPlayer then
		local LastOrientation = Object.Orientation
		local connection
		connection = RunService.RenderStepped:Connect(function(deltaTime)
			if Object and Object.Parent then
				local CurrentOrientation = Object.Orientation
				local deltaOrientation = CurrentOrientation - LastOrientation
				local Velocity = deltaOrientation / deltaTime
				Object.AssemblyLinearVelocity = Velocity
				LastOrientation = CurrentOrientation
			else
				connection:Disconnect()
			end
		end)
		table.insert(Debris, connection)
	end
end)

ReplicateConveyor.OnClientEvent:Connect(function(inst, Speed)
	local texture = inst:FindFirstChild("Texture")
	if texture then
		local Tween = TweenService:Create(texture, TweenInfo.new(math.abs(Speed), Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, false, 0), {
			OffsetStudsV = texture.OffsetStudsV - math.abs(Speed * 2.5)
		}):Play()

		local connection
		connection = RunService.RenderStepped:Connect(function()
			if inst and inst.Parent then
				inst.AssemblyLinearVelocity = inst.CFrame.LookVector * Speed
			else
				connection:Disconnect()
			end
		end)
		table.insert(Debris, connection)
	end
end)

ConnectDeathPart.OnClientEvent:Connect(function(Part: Part)
	local touchedConnection
	touchedConnection = Part.Touched:Connect(function(Hit)
		if Hit.Parent:FindFirstChild("Humanoid") then
			local Player = Players:GetPlayerFromCharacter(Hit.Parent)
			if Player and Player == LocalPlayer then
				ConnectDeathPart:FireServer()
			end
		end
	end)

	Part.AncestryChanged:Connect(function(_, parent)
		if not parent then
			touchedConnection:Disconnect()
		end
	end)
end)

FullRoundEnd.OnClientEvent:Connect(function()
	cleanUpConnections()
end)

return ReplicateMovingParts

yes

I’m not exactly sure how your script works, but I’m guessing the connections aren’t being cleaned up correctly, or too much are being called

1 Like