Extremely high memory usage, don't know where it came from

Hey,

Recently I have discovered that I use a lot of memory for some reason. I opened an empty place (deleted baseplate, added spawnlocaton in the air) and I had 1.5 gigabytes of ram being used.

I would not see this as a problem as I have 16 gb of ram, but I am confused about how it can be so high. I’m making a game and I don’t want people getting 2 gb+ memory usage.

My micro profiler:

My hierachy in the empty place:

In the game I am developing right now I get 2+ gigabytes consistently, I will also give you my microprofiler for that.

Also worth saying is that when I open a game with just the scripts and UI, I get 700MB instead of the usual 2GB, which leads me to believe that it’s not the scripts fault.

The building is mostly meshes & unions, all modeled and put into folders.

It started happening yesterday, and my friends have it aswell (I use Windows, they use OSX)
I don’t understand where the render comes from because it’s literally an interactive main menu that tweens towards your mouse whenever you move it.
I have streamingenabled on because I tried to make a chunk loading system but it just made the game more laggy.
If you need any more information, please tell me and I will give it to you

Thanks!

3 Likes

I’m not an expert but I was told that memory comes from your code (as well as builds). How memory is created is by referencing variables, or having connections being constantly created without being disconnected.

Have you added anything recently that was a big feature?

Are any events being put into a loop and not being disconnected?

I’d need to see the code in order to help you, if you have a general idea on where the problem started that would be a good way to start checking you scripts.

I can put a bunch of my main scripts code here if you wish

Sure I could quickly scan through them.

– Main menu script, manages team change, UI buttons, etc
Sorry if it’s quite sloppy code, haven’t really made it to share, just so I can understand it myself
UI looks like this, idk if it’s important:

wait(3)
local con 
local debounce = true
--[[
	
	
	Disabling CoreGuis
--]]
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack,false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.EmotesMenu,false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList,false)

workspace.MainMenu:WaitForChild("right1"):WaitForChild("one"):WaitForChild("Frame"):WaitForChild("plrframe"):WaitForChild("bull"):WaitForChild("ImageLabel").Image = "https://www.roblox.com/bust-thumbnail/image?userId=".. game.Players.LocalPlayer.UserId .."&width=420&height=420&format=png"
workspace.MainMenu.right1.one.Frame.plrframe.tex.Text = game.Players.LocalPlayer.Name
workspace.MainMenu.right1.one.Frame.plrframe.Bottom.Text = game.Players.LocalPlayer.UserId
workspace.MainMenu.right1.one.Frame.clearnace.TextLabel.Text = tostring(game.Players.LocalPlayer:GetRoleInGroup(game.ReplicatedStorage.groupid.Value))

script.music:Play()
local loadables = workspace:GetDescendants() 

local amount_loaded = 0
local oldamount  = 0
game.Players.LocalPlayer.PlayerGui:SetTopbarTransparency(0)
for i = 1, #loadables do
	
if amount_loaded - oldamount   >= 100 then

		oldamount = amount_loaded
		 game.Players.LocalPlayer.PlayerGui.loading["0"].Frame:TweenPosition(UDim2.new(0,0,-2.5 - (4/(#loadables/amount_loaded)),0),"InOut","Sine",5,true)
	end
    coroutine.wrap(function()
	        game.ContentProvider:PreloadAsync({loadables[i]})
	        amount_loaded = amount_loaded + 1
       

    end)()
end


while amount_loaded ~= #loadables do

	wait()
end
local DefaultCFrame
local introbusy
spawn(function()

local Mouse = game.Players.LocalPlayer:GetMouse()
local Camera = game.Workspace.CurrentCamera

local cam = game.Workspace.CurrentCamera
cam.CameraType = "Scriptable"
cam.CameraSubject = workspace.campart
cam.CFrame = workspace.campart.CFrame

 DefaultCFrame = workspace.campart.CFrame
local Scale = 100
introbusy = true
function Update()
	if introbusy == true then
	    -- get the center of the screen
	    local Center = Vector2.new(Camera.ViewportSize.X/2, Camera.ViewportSize.Y/2)
	    -- get the movement (it's in studs, and the mouse properties are in pixels, so you want to divide it by your scale to not move the camera really really far)
	    local MoveVector = Vector3.new((Mouse.X-Center.X)/(-Scale), (Mouse.Y-Center.Y)/(-Scale), 0)
	    -- CFrame * CFrame makes it work the same regardless of rotation, where addition just makes it work for one direction
	 --   Camera.CFrame = DefaultCFrame * CFrame.new(DefaultCFrame.p + MoveVector)
	--Camera.CFrame = DefaultCFrame * CFrame.new(MoveVector)
	--Camera.CFrame = DefaultCFrame * CFrame.new(DefaultCFrame.p + MoveVector)
	--Camera.CFrame = Camera.CFrame:Lerp(CFrame.new(DefaultCFrame.p,MoveVector), 0.5)
	game:GetService("TweenService"):Create(workspace.CurrentCamera, TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {CFrame = DefaultCFrame * CFrame.Angles(math.rad(MoveVector.Y), math.rad(MoveVector.X), 0)}):Play()	
				
	--Camera.CFrame = DefaultCFrame * CFrame.Angles(math.rad(MoveVector.Y), math.rad(MoveVector.X), 0)
	end
end

local gui = workspace.MainMenu.left1.one.Frame.DividerRound.ScrollingFrame
local currentpos = UDim2.new(0.05,0,0,0)
for i,v in pairs(game.Teams:GetChildren()) do wait()
		if v.Name ~= "Class-D" and v.Name ~= "Unassigned" and v.Name ~= "Solitary" then
		
			if game.Players.LocalPlayer:GetRankInGroup(v.id.Value) >= 1 or game.Players.LocalPlayer:GetRankInGroup(v.id.Value)  == 1  or  (v.Name == "Class-D" and game.Players.LocalPlayer:GetRankInGroup(game.ReplicatedStorage.groupid.Value) == 0)  then
				if (v.Name == "Class-D" and game.Players.LocalPlayer:GetRankInGroup(game.ReplicatedStorage.groupid.Value) >= 5) then return end
				local clone = workspace.MainMenu.left1.one.Frame.DividerRound.ScrollingFrame.TextButton:Clone()
				clone.MouseButton1Click:connect(function()
					clone.TextButton_Roundify_6px:TweenSize(UDim2.new(1,6,1,6),"InOut","Linear",0.21,true)
					local clone2 = script.Sounds.click:Clone()
					clone2.Parent = script
					clone2:Play()
					script.team.Value = clone.Text
					workspace.MainMenu.left1.one.Frame.TextButton:TweenPosition(UDim2.new(0,-1,0.75,0),"InOut",0.5,true)
					workspace.MainMenu.right1.one.Frame.Frame.TextLabel.Text = clone.Text
					workspace.MainMenu.right2.one.Frame.plrframe.Stats.Text = clone.text
			
					workspace.MainMenu.right2.one.Frame.plrframe.Bottom.Text = game.Teams:FindFirstChild(clone.Text).desc.Value
					wait(0.21)
					clone2:Destroy()
					clone.TextButton_Roundify_6px:TweenSize(UDim2.new(1,0,1,0),"InOut","Sine",0.21,true)
				end)
			clone.Parent = gui
		if i == 1 then
			clone.Position = currentpos
			local setpos = currentpos
			clone.MouseEnter:connect(function()
			clone:TweenPosition(setpos + UDim2.new(0.05,0,0,0,0),"InOut","Sine",0.5,true)
		end)
			clone.MouseLeave:connect(function()
			clone:TweenPosition(setpos,"InOut","Sine",0.5,true)
		end)
		else
			clone.Position = currentpos + UDim2.new(0,0,0.04,0)
			currentpos = currentpos + UDim2.new(0,0,0.04,0)
			local setpos = currentpos
			clone.MouseEnter:connect(function()
			clone:TweenPosition(setpos + UDim2.new(0.05,0,0,0,0),"InOut","Sine",0.5,true)
		end)
			clone.MouseLeave:connect(function()
			clone:TweenPosition(setpos,"InOut","Sine",0.5,true)
		end)
		end
		
			clone.Text = v.Name
			clone.Name = v.Name
			clone.TextButton_Roundify_12px.UIGradient.Color = ColorSequence.new(v.TeamColor.Color,Color3.new(0.3125,0.3125,0.3125))
		end
	end
end



gui.TextButton.Visible = false

con = game:GetService("RunService").RenderStepped:Connect(Update) 

end)
-- On game start display text & tween etc
wait(1)
 game.Players.LocalPlayer.PlayerGui.loading["0"].Frame:TweenPosition(UDim2.new(0,0,-6.5,0),"InOut","Sine",5,true)
wait(5)
for i = 1,30 do wait()
	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency = 	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency + 0.033333333333333
end
game.Players.LocalPlayer.PlayerGui.dot.TextLabel.Text = "This game was designed by the Oneware Studios team."
for i = 1,30 do wait()
	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency = 	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency - 0.033333333333333
end
wait(2)
for i = 1,30 do wait()
	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency = 	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency + 0.033333333333333
end
game.Players.LocalPlayer.PlayerGui.dot.TextLabel.Text = "Welcome, " .. game.Players.LocalPlayer.Name
for i = 1,30 do wait()
	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency = 	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency - 0.033333333333333
end
wait(2)

spawn(function()
for i = 1,30 do wait()
	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency = 	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency +0.033333333333333
	game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency = game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency + 0.0333333333333
game.Players.LocalPlayer.PlayerGui.loading["0"]["0"].ImageTransparency = game.Players.LocalPlayer.PlayerGui.loading["0"]["0"].ImageTransparency + 0.0333333333333
game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency = game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency +0.03

end
game.Players.LocalPlayer.PlayerGui.loading.Enabled = false
end)
spawn(function()

local steps = 25

for i,v in pairs(game.Players.LocalPlayer.PlayerGui.dot.Frame:GetChildren()) do wait()
	spawn(function()
		for i = 1,steps do wait()
			v.BackgroundTransparency = v.BackgroundTransparency + 1/steps
		end
	end)
end

end)
-- Button events.'



workspace.MainMenu.left1.one.Frame.TextButton.MouseButton1Click:connect(function()
			workspace.MainMenu.left1.one.Frame.TextButton:TweenPosition(UDim2.new(0,-1,1.75,0),"InOut","Sine",1,true)
			local clone2 = script.Sounds.click:Clone()
			clone2.Parent = script
			clone2:Play()
			introbusy = false
			wait(0.1)
			game:GetService("TweenService"):Create(workspace.CurrentCamera, TweenInfo.new(4, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {CFrame = workspace.campart.campart.CFrame}):Play()	
			wait(4)
			
			DefaultCFrame = workspace.campart.campart.CFrame
			introbusy = true
			debounce = false
			clone2:Destroy()
end)
local currentpos2 = UDim2.new(0.5,0,0.05,0)
for i,v in pairs(game.ReplicatedStorage.news:GetChildren()) do
	local clone = workspace.MainMenu.left2.one.Frame.news.ScrollingFrame.NewsFrame:Clone()
	clone.Parent = workspace.MainMenu.left2.one.Frame.news.ScrollingFrame
	if i == 1 then
			clone.Position = currentpos2
			
			local setpos = currentpos2
			print(setpos)
			currentpos = setpos + UDim2.new(0,0,0.125,0)
	else
			local setpos = currentpos2
			currentpos2 = setpos + UDim2.new(0,0,0.125,0)
			clone.Position = currentpos2
	end
	clone.Name = v:FindFirstChild("Name").Value
	clone.headline.Text = v:FindFirstChild("Name").Value
	clone.TextLabel.Text = v.Desc.Value
end

workspace.MainMenu.right2.one.Frame.TextButton.MouseButton1Click:Connect(function()
		 local steps = 25
		if debounce == false then
			debounce = true
	for i,v in pairs(game.Players.LocalPlayer.PlayerGui.dot.Frame:GetChildren()) do wait()
		spawn(function()
			for i = 1,steps do wait()
				v.BackgroundTransparency = v.BackgroundTransparency - 1/steps
			end
		end)
end
local val = game.ReplicatedStorage.changeteam:InvokeServer(script.team.Value)
repeat wait() until val ~= nil
wait(1)
if val == true then
	introbusy = false
	wait()
	con:Disconnect()
	workspace.CurrentCamera.CameraType = Enum.CameraType.Custom
	workspace.CurrentCamera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid
	workspace.CurrentCamera.CFrame = game.Players.LocalPlayer.Character.Head.CFrame
	for i,v in pairs(game.Players.LocalPlayer.PlayerGui.dot.Frame:GetChildren()) do wait()
		game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack,true)
	

	spawn(function()
		for i = 1,steps do wait()
			v.BackgroundTransparency = v.BackgroundTransparency + 1/steps
		end
	end)
	end
	end
end
end)```

Head rotation:
I literally copied it out of
https://devforum.roblox.com/uploads/short-url/12Kc4u1yNH8dOc6Z1yJ5BYcFGIQ.rbxl
there
walking sound script:

local Character = Player.Character

local DefaultSound = Character:WaitForChild("HumanoidRootPart"):WaitForChild("Running").SoundId

local MaterialTable = {
    [Enum.Material.Grass] = "rbxassetid://379482039",
    [Enum.Material.Concrete] = "rbxassetid://3190903775",
    [Enum.Material.Plastic] = "rbxassetid://379483672"
    
}

local Assets = {"rbxassetid://256575709","rbxassetid://256575709"}
game:GetService("ContentProvider"):PreloadAsync(Assets)
function update()

    local FloorMaterial = Character.Humanoid.FloorMaterial
    if MaterialTable[FloorMaterial] then
        Character.HumanoidRootPart.Running.SoundId = MaterialTable[FloorMaterial]
        Character.HumanoidRootPart.Running.PlaybackSpeed = (0.8*Character.Humanoid.WalkSpeed) / 10
    else
        Character.HumanoidRootPart.Running.SoundId = DefaultSound
        Character.HumanoidRootPart.Running.PlaybackSpeed = 1
    end
end
Character.Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
	update()
end)

The code isn’t bad but there are definitely areas that can be improved and cleaned up.

What you can do:

  1. Split repetitive code into functions

This is quite self explanatory, first reduce the amount of code., adjust the function so it can support many things if needed.

  1. Use TweenService for effects

TweenService is a element ROBLOX introduced which means it was built for high performance. With all those for loops (which is actual lua), it will be much more efficient to use TweenService. TweenService also provides delay arguments and much more to prevent using wait, delay, and etc. TweenService also has a completed function which can help you remove these waits.

  1. Avoid creating so many threads

I’ve noticed you’ve made multiple threads inside of loops which causes performance issues, an easy way to solve this is to use TweenService to prevent yielding the thread.

  1. coroutine over spawn

There are lot’s of arguments on this but usually coroutine isn’t scary.

spawn(function()
-- code
end)

coroutine.wrap(function()

end)()
1 Like

Okay, I will change everything to that and see if it’s improved! I’ll keep you updated.

Okay, I have done it, I got this right now:

```wait(3)
local con 
local debounce = true
--[[
	
	
	Disabling CoreGuis
--]]
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack,false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.EmotesMenu,false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList,false)

workspace.MainMenu:WaitForChild("right1"):WaitForChild("one"):WaitForChild("Frame"):WaitForChild("plrframe"):WaitForChild("bull"):WaitForChild("ImageLabel").Image = "https://www.roblox.com/bust-thumbnail/image?userId=".. game.Players.LocalPlayer.UserId .."&width=420&height=420&format=png"
workspace.MainMenu.right1.one.Frame.plrframe.tex.Text = game.Players.LocalPlayer.Name
workspace.MainMenu.right1.one.Frame.plrframe.Bottom.Text = game.Players.LocalPlayer.UserId
workspace.MainMenu.right1.one.Frame.clearnace.TextLabel.Text = tostring(game.Players.LocalPlayer:GetRoleInGroup(game.ReplicatedStorage.groupid.Value))

script.music:Play()
local loadables = {}

local amount_loaded = 0
local oldamount  = 0
game.Players.LocalPlayer.PlayerGui:SetTopbarTransparency(0)
for i = 1, #loadables do
	
if amount_loaded - oldamount   >= 100 then

		oldamount = amount_loaded
		 game.Players.LocalPlayer.PlayerGui.loading["0"].Frame:TweenPosition(UDim2.new(0,0,-2.5 - (4/(#loadables/amount_loaded)),0),"InOut","Sine",5,true)
	end
    coroutine.wrap(function()
	        game.ContentProvider:PreloadAsync({loadables[i]})
	        amount_loaded = amount_loaded + 1
       

    end)()
end


while amount_loaded ~= #loadables do

	wait()
end
local DefaultCFrame
local introbusy
coroutine.wrap(function()

local Mouse = game.Players.LocalPlayer:GetMouse()
local Camera = game.Workspace.CurrentCamera

local cam = game.Workspace.CurrentCamera
cam.CameraType = "Scriptable"
cam.CameraSubject = workspace.campart
cam.CFrame = workspace.campart.CFrame

 DefaultCFrame = workspace.campart.CFrame
local Scale = 100
introbusy = true
function Update()
	if introbusy == true then
	    -- get the center of the screen
	    local Center = Vector2.new(Camera.ViewportSize.X/2, Camera.ViewportSize.Y/2)
	    -- get the movement (it's in studs, and the mouse properties are in pixels, so you want to divide it by your scale to not move the camera really really far)
	    local MoveVector = Vector3.new((Mouse.X-Center.X)/(-Scale), (Mouse.Y-Center.Y)/(-Scale), 0)
	    -- CFrame * CFrame makes it work the same regardless of rotation, where addition just makes it work for one direction
	 --   Camera.CFrame = DefaultCFrame * CFrame.new(DefaultCFrame.p + MoveVector)
	--Camera.CFrame = DefaultCFrame * CFrame.new(MoveVector)
	--Camera.CFrame = DefaultCFrame * CFrame.new(DefaultCFrame.p + MoveVector)
	--Camera.CFrame = Camera.CFrame:Lerp(CFrame.new(DefaultCFrame.p,MoveVector), 0.5)
	game:GetService("TweenService"):Create(workspace.CurrentCamera, TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {CFrame = DefaultCFrame * CFrame.Angles(math.rad(MoveVector.Y), math.rad(MoveVector.X), 0)}):Play()	
				
	--Camera.CFrame = DefaultCFrame * CFrame.Angles(math.rad(MoveVector.Y), math.rad(MoveVector.X), 0)
	end
end

local gui = workspace.MainMenu.left1.one.Frame.DividerRound.ScrollingFrame
local currentpos = UDim2.new(0.05,0,0,0)
for i,v in pairs(game.Teams:GetChildren()) do wait()
		if v.Name ~= "Class-D" and v.Name ~= "Unassigned" and v.Name ~= "Solitary" then
		
			if game.Players.LocalPlayer:GetRankInGroup(v.id.Value) >= 1 or game.Players.LocalPlayer:GetRankInGroup(v.id.Value)  == 1  or  (v.Name == "Class-D" and game.Players.LocalPlayer:GetRankInGroup(game.ReplicatedStorage.groupid.Value) == 0)  then
				if (v.Name == "Class-D" and game.Players.LocalPlayer:GetRankInGroup(game.ReplicatedStorage.groupid.Value) >= 5) then return end
				local clone = workspace.MainMenu.left1.one.Frame.DividerRound.ScrollingFrame.TextButton:Clone()
				clone.MouseButton1Click:connect(function()
					clone.TextButton_Roundify_6px:TweenSize(UDim2.new(1,6,1,6),"InOut","Linear",0.21,true)
					local clone2 = script.Sounds.click:Clone()
					clone2.Parent = script
					clone2:Play()
					script.team.Value = clone.Text
					workspace.MainMenu.left1.one.Frame.TextButton:TweenPosition(UDim2.new(0,-1,0.75,0),"InOut",0.5,true)
					workspace.MainMenu.right1.one.Frame.Frame.TextLabel.Text = clone.Text
					workspace.MainMenu.right2.one.Frame.plrframe.Stats.Text = clone.text
			
					workspace.MainMenu.right2.one.Frame.plrframe.Bottom.Text = game.Teams:FindFirstChild(clone.Text).desc.Value
					wait(0.21)
					clone2:Destroy()
					clone.TextButton_Roundify_6px:TweenSize(UDim2.new(1,0,1,0),"InOut","Sine",0.21,true)
				end)
			clone.Parent = gui
		if i == 1 then
			clone.Position = currentpos
			local setpos = currentpos
			clone.MouseEnter:connect(function()
			clone:TweenPosition(setpos + UDim2.new(0.05,0,0,0,0),"InOut","Sine",0.5,true)
		end)
			clone.MouseLeave:connect(function()
			clone:TweenPosition(setpos,"InOut","Sine",0.5,true)
		end)
		else
			clone.Position = currentpos + UDim2.new(0,0,0.04,0)
			currentpos = currentpos + UDim2.new(0,0,0.04,0)
			local setpos = currentpos
			clone.MouseEnter:connect(function()
			clone:TweenPosition(setpos + UDim2.new(0.05,0,0,0,0),"InOut","Sine",0.5,true)
		end)
			clone.MouseLeave:connect(function()
			clone:TweenPosition(setpos,"InOut","Sine",0.5,true)
		end)
		end
		
			clone.Text = v.Name
			clone.Name = v.Name
			clone.TextButton_Roundify_12px.UIGradient.Color = ColorSequence.new(v.TeamColor.Color,Color3.new(0.3125,0.3125,0.3125))
		end
	end
end



gui.TextButton.Visible = false

con = game:GetService("RunService").RenderStepped:Connect(Update) 

end)()
-- On game start display text & tween etc
wait(1)
 game.Players.LocalPlayer.PlayerGui.loading["0"].Frame:TweenPosition(UDim2.new(0,0,-6.5,0),"InOut","Sine",5,true)
wait(5)
game:GetService("TweenService"):Create(game.Players.LocalPlayer.PlayerGui.dot.TextLabel,TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {TextTransparency= 1}):Play()
wait(1)
	
game.Players.LocalPlayer.PlayerGui.dot.TextLabel.Text = "This game was designed by the Oneware Studios team."

	game:GetService("TweenService"):Create(game.Players.LocalPlayer.PlayerGui.dot.TextLabel,TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {TextTransparency= 0}):Play()

wait(2)

	game:GetService("TweenService"):Create(game.Players.LocalPlayer.PlayerGui.dot.TextLabel,TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {TextTransparency= 1}):Play()
wait(1)


game.Players.LocalPlayer.PlayerGui.dot.TextLabel.Text = "Welcome, " .. game.Players.LocalPlayer.Name
game:GetService("TweenService"):Create(game.Players.LocalPlayer.PlayerGui.dot.TextLabel,TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {TextTransparency= 0}):Play()




wait(2)

coroutine.wrap(function()
for i = 1,30 do wait()
	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency = 	game.Players.LocalPlayer.PlayerGui.dot.TextLabel.TextTransparency +0.033333333333333
	game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency = game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency + 0.0333333333333
game.Players.LocalPlayer.PlayerGui.loading["0"]["0"].ImageTransparency = game.Players.LocalPlayer.PlayerGui.loading["0"]["0"].ImageTransparency + 0.0333333333333
game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency = game.Players.LocalPlayer.PlayerGui.loading["0"].Frame.BackgroundTransparency +0.03

end
game.Players.LocalPlayer.PlayerGui.loading.Enabled = false
end)()
coroutine.wrap(function()

local steps = 25

for i,v in pairs(game.Players.LocalPlayer.PlayerGui.dot.Frame:GetChildren()) do wait()
	
	game:GetService("TweenService"):Create(v,TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {BackgroundTransparency= 1}):Play()



end

end)()
-- Button events.'



workspace.MainMenu.left1.one.Frame.TextButton.MouseButton1Click:connect(function()
			workspace.MainMenu.left1.one.Frame.TextButton:TweenPosition(UDim2.new(0,-1,1.75,0),"InOut","Sine",1,true)
			local clone2 = script.Sounds.click:Clone()
			clone2.Parent = script
			clone2:Play()
			introbusy = false
			wait(0.1)
			game:GetService("TweenService"):Create(workspace.CurrentCamera, TweenInfo.new(4, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {CFrame = workspace.campart.campart.CFrame}):Play()	
			wait(4)
			
			DefaultCFrame = workspace.campart.campart.CFrame
			introbusy = true
			debounce = false
			clone2:Destroy()
end)
local currentpos2 = UDim2.new(0.5,0,0.05,0)
for i,v in pairs(game.ReplicatedStorage.news:GetChildren()) do
	local clone = workspace.MainMenu.left2.one.Frame.news.ScrollingFrame.NewsFrame:Clone()
	clone.Parent = workspace.MainMenu.left2.one.Frame.news.ScrollingFrame
	if i == 1 then
			clone.Position = currentpos2
			
			local setpos = currentpos2
			print(setpos)
			currentpos = setpos + UDim2.new(0,0,0.125,0)
	else
			local setpos = currentpos2
			currentpos2 = setpos + UDim2.new(0,0,0.125,0)
			clone.Position = currentpos2
	end
	clone.Name = v:FindFirstChild("Name").Value
	clone.headline.Text = v:FindFirstChild("Name").Value
	clone.TextLabel.Text = v.Desc.Value
end

workspace.MainMenu.right2.one.Frame.TextButton.MouseButton1Click:Connect(function()
		 local steps = 25
		if debounce == false then
			debounce = true
	for i,v in pairs(game.Players.LocalPlayer.PlayerGui.dot.Frame:GetChildren()) do wait()
	coroutine.wrap(function()
			game:GetService("TweenService"):Create(v,TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {BackgroundTransparency= 0}):Play()


		end)()
end
local val = game.ReplicatedStorage.changeteam:InvokeServer(script.team.Value)
repeat wait() until val ~= nil
wait(1)
if val == true then
	introbusy = false
	wait()
	con:Disconnect()
	workspace.CurrentCamera.CameraType = Enum.CameraType.Custom
	workspace.CurrentCamera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid
	workspace.CurrentCamera.CFrame = game.Players.LocalPlayer.Character.Head.CFrame
	for i,v in pairs(game.Players.LocalPlayer.PlayerGui.dot.Frame:GetChildren()) do wait()
		game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack,true)
	

coroutine.wrap(function()
		game:GetService("TweenService"):Create(v,TweenInfo.new(1, Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {BackgroundTransparency= 1}):Play()


	end)()
	end
	end
end
end)``

Again a few things:

  1. You don’t need waits and use TweenService

TweenService provides a delay argument so use it to your advantage. I’ve also noticed once more that you have a for loop tweening transparent of images, texts and backgrounds. Use TweenService this would get rid of the thread and the loop entirely. You can use Tween.Completed:Wait() to yield if needed.

  1. You shouldn’t use RunService RenderStepped

RunService is used poorly there. First off RenderStepped will directly affect your FPS. Heartbeat or Stepped would be better in this case.

  1. Use Functions / Clean you code

It’s too hard for me to read your code right now, I’d need you to properly indent it and place it into functions to reduce the total size

  1. Avoid Deprecated Stuff

:Connect() over :connect()

There’s a lot of other smaller stuff I haven’t mentioned but after editing it once more see if there are any changes or improvements. I think RenderStepped might be the biggest issue

I did most of it except point 3, but my memory usage only has increased for some reason.
I noticed that this happened, I have not seen this before:


I don’t know what PhysicsStepped, WaitingScriptJob, $script, or WorkerRunJob means, but it’s taking a lot of memory. Do you know what that is?

Are there any other scripts that exists that you haven’t showed me? Could you show me the edited script once more?

EDIT: Are you testing in studio or real server? I find that memory in studio is higher then in real servers.

Yeah, I already figured, will test right now.

1 Like

oh my god, turns out that’s actually it. 400mb usage in actual roblox game, 2.4gb in studio… thanks so much!

4 Likes

ive had same issue with games like Phantom Forces, Bad business etc. Month ago it was fine recently it slowly using more and more memory. Im 100% sure its problem with the roblox client

I’m only replying on the behalf that this is a building issue and not a script memory issue. I use some of these ideas in my games and they worked out well for reducing some memory.

First, compress all your decals/textures.

  • I use ImageCompressor, you can compress a lot and still keep decent resolution.
  • Compressing all your images will help reduce memory usage.

Second, develop your own chunk loading system.

  • You stated you already made it, but it ended up making things laggier. Unless you have tons of un-anchored parts, you most likely just did it wrong.
  • Whenever a player is in a part of the map, just clientsidedly remove the other parts of the map that they can’t see.
  • Or a simple magnitude check could work but those are weird to work with and the method I just suggested works better in most cases.

Switch from UnionOperations to MeshParts.

  • To do this, just export your UnionOperations as objects, create a MeshPart instance, and drag in the object file where it asks for MeshId or something like that.
  • Another tip is to export meshparts and remove tons of triangles from them.

Any part that can’t be touched by the player/out of reach should be set to CanCollide = false.

  • It’s super small but it helps reduce memory.

Hope some of this helped.

fyi, this post is already like 7 months old but thanks anyways

1 Like

Oops my bad, didn’t see someone bumped it.

1 Like