FreeEntity FreeTexture FreeImage and memory

Blitz3D Forums/Blitz3D Beginners Area/FreeEntity FreeTexture FreeImage and memory

RemiD(Posted 2011) [#1]
Hi, :)

I am trying to use the blitz3d commands "FreeEntity" and "FreeTexture" and they don't seem to remove the mesh and the texture from the memory (i mean the RAM).

You can try this code to see what i mean :
Note : the program is in fullscreen mode in order to stop it when pressing CTRL + ALT + DEL.
Dim PanneauMesh(1)
Dim PanneauColor(1)

Graphics3D 1024,768,32,1
;ClearTextureFilters
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Global Origine = CreatePivot()
PositionEntity Origine,0,0,0

Origine_Mesh = CreateCube()
ScaleMesh Origine_Mesh,0.1/2,1024.0/2,0.1/2
EntityColor Origine_Mesh,255,000,000
EntityFX Origine_Mesh,1
PositionEntity Origine_Mesh,EntityX(Origine,True),EntityY(Origine,True),EntityZ(Origine,True)
EntityParent Origine_Mesh,Origine,True
	
Global Camera = CreateCamera()
CameraRange Camera,0.1,2048.0
CameraClsColor Camera,255,000,255
PositionEntity Camera,EntityX(Origine,True),EntityY(Origine,True)+1.6,EntityZ(Origine,True)-10
EntityParent Camera,Origine,True

Global StartSec% = MilliSecs()
Global Sec% = 0
Global ScreenTitleState% = 100
DoOnce% = 0
Debug% = 1

Repeat

	Cls
	
	If (DoOnce% = 0)
		If (Sec% > 5)
			ScreenTitleState% = 0			
			DoOnce% = 1
		EndIf
	EndIf	
	
	;Manages the Screen state		
	If (ScreenTitleState% = 0)
		ScreenTitle_Create()			
	ElseIf (ScreenTitleState% = 1)
		ScreenTitle_Update()
	ElseIf (ScreenTitleState% = 2)
		ScreenTitle_Free()
	EndIf
	
	Sec% = (MilliSecs() - StartSec%)/1000
	
	;Mode Wireframe
	If KeyDown(2)
		WireFrame True
	Else
		WireFrame False
	EndIf
	
	;Calculates and renders the 3D scene	
	RenderWorld
	
	;Displays Debug infos
	If (Debug% = 1)	 		 	
		Color 255,255,255
		Text 20,20,"Tris : " + TrisRendered()  
		Text 20,40,"Sec% : " + Sec% 			
	EndIf
	
Flip False
	
Until (KeyDown(1) = True) Or (Sec% = 20)



Function ScreenTitle_Create()
	
	;Creates the Mesh Panneau
	PanneauMesh(1) = CreateMesh()
	PanneauSurface = CreateSurface(PanneauMesh(1))  
	AddVertex PanneauSurface,-1.0,+0.75,0.0,0.000,0.125
	AddVertex PanneauSurface,+1.0,+0.75,0.0,1.000,0.125  
	AddVertex PanneauSurface,-1.0,-0.75,0.0,0.000,0.875 
	AddVertex PanneauSurface,+1.0,-0.75,0.0,1.000,0.875  
	AddTriangle PanneauSurface,0,1,2  
	AddTriangle PanneauSurface,2,1,3  
	UpdateNormals PanneauMesh(1)
	EntityColor PanneauMesh(1),255,255,255 
	EntityFX PanneauMesh(1),1  	
	PositionMesh PanneauMesh(1),0,0,0
	;EntityOrder PanneauMesh(1),-1	
	
	;Creates the Texture Panneau
	PanneauColor(1) = CreateTexture(1024,1024)
	SetBuffer TextureBuffer(PanneauColor(1))
	ClsColor 000,000,000
	Cls
	Font_TimesNewRomanTitre = LoadFont("Times New Roman",75,True,False,False)
	SetFont Font_TimesNewRomanTitre
	Color 255,255,255
	Text 1024.0/2,512-75,"TITLE",True,False	
	FreeFont Font_TimesNewRomanTitre	
	SetBuffer BackBuffer()	
	EntityTexture PanneauMesh(1),PanneauColor(1),0,0
	
	PositionEntity PanneauMesh(1),EntityX(Camera,True),EntityY(Camera,True),EntityZ(Camera,True)+1.0
	EntityParent PanneauMesh(1),Camera,True	

	;Parents and Positions the Camera on the Origine	
	PositionEntity Camera,EntityX(Origine,True),EntityY(Origine,True)+1.6,EntityZ(Origine,True)-10
	EntityParent Camera,Origine,True
		
	ScreenTitleState% = 1
	
End Function



Function ScreenTitle_Update()

	;Updates the Mesh Panneau	
			
	;Updates EcranTitreState%
	If (Sec% > 10)	
		ScreenTitleState% = 2	
	EndIf

End Function



Function ScreenTitle_Free()

	;Frees the Mesh Panneau
	FreeEntity PanneauMesh(1)				
	;Frees the Texture Panneau
	FreeTexture PanneauColor(1)
	
	ScreenTitleState% = 3
	
End Function



End


The program creates a simple scene.

From 0 to 5 secs, if i stop the program with CTRL + ALT + DEL and i check the number of ko blitzcc.exe uses, it is around 13000ko

After 5secs, the program creates a mesh (a quad) and a texture (1024x1024pixels) and displays them at the screen.

From 6 to 10 secs, if i stop the program with CTRL + ALT + DEL and i check the number of ko blitzcc.exe uses, it is around 25000ko

After 10secs, the program deletes the mesh and the texture with FreeEntity and FreeTexture.

However, from 11 to 20 secs, if i stop the program with CTRL + ALT + DEL and i check the number of ko blitzcc.exe uses, it is around 21000ko

Why ? In my understanding, after the deletion of the mesh and of the texture, blitzcc.exe should use the same amount of ko than before the mesh and texture were created.

Imagine i use a similar code to create and to delete many meshes and textures, if blitz3d behaves this way, there will be a memory leak...

Can you give me some advices about this please ?

Thanks,
Good day,

Last edited 2011


andy_mc(Posted 2011) [#2]
To check if there is a memory leak, you should re-create the meshes and free them several times, keeping an eye on memory use.


Yasha(Posted 2011) [#3]
andy_mc's right.

As a bit of explanation... Task Manager is not a reliable way of measuring the actual memory use of an application, because it lists the maximum amount of memory allocated to it by the OS. The OS isn't going to start reclaiming tiny amounts of memory like that immediately, because the program will usually want them again, so it keeps the excess memory for the time being.

(At least I think that's what happens.)

By following andy_mc's suggestion, you'll be asking the slightly more reliable question of "does the OS allocate new memory for each new object, even though it should be able to use the space from the last one?".

As a couple of aside notes -

- If you run your program in windowed mode, you could have it on the screen next to the task manager - might be useful. If you want the program to stop when it's not in focus, use window mode 6 rather than 2.

- FreeTexture doesn't necessarily delete a texture.

Textures have a "reference count", which keeps track of how many things are using it: it starts at one, to represent the variable you loaded it into. When you apply the texture to an entity or brush, the reference count increases by one, and when you paint over it or free the entity/brush it was on, it decrements by one. You can also use FreeTexture once to decrement the refcount by one, which ensures that everything adds up. When the texture's reference count hits zero, the texture is deleted. This is why it's common to see code that loads a mesh, loads a texture, applies it and then frees the texture immediately: the texture will be perfectly safe as long as the mesh using it still exists, and it means one less thing to clean up later.

While there's absolutely nothing wrong with the way you're doing it, this piece of information may be of interest if you're trying to track memory.

I think (can't remember) that Blitz also caches textures in the background by filename, in case the same entities try to load more than one instance of the same texture - I could be wrong, but that actually seems like it might be an explanation for your odd memory use pattern.


RemiD(Posted 2011) [#4]

keeping an eye on memory use.




Task Manager is not a reliable way of measuring the actual memory use of an application



Ok, so how do you track the memory use ?




FreeTexture doesn't necessarily delete a texture.

Textures have a "reference count", which keeps track of how many things are using it: it starts at one, to represent the variable you loaded it into. When you apply the texture to an entity or brush, the reference count increases by one, and when you paint over it or free the entity/brush it was on, it decrements by one. You can also use FreeTexture once to decrement the refcount by one, which ensures that everything adds up. When the texture's reference count hits zero, the texture is deleted. This is why it's common to see code that loads a mesh, loads a texture, applies it and then frees the texture immediately: the texture will be perfectly safe as long as the mesh using it still exists, and it means one less thing to clean up later.



I wasn't aware of that. I have tried to delete the texture before the mesh :
;Frees the Texture Panneau
FreeTexture PanneauColor(1)
;Frees the Mesh Panneau
FreeEntity PanneauMesh(1)				


And there is still 21000ko of memory used.

I don't understand...


Rob the Great(Posted 2011) [#5]
Correct me if I'm wrong, but when you free something from memory, doesn't it just mark the space it occupies as "ready to be replaced"?

In other words, if you deleted a mesh, isn't the mesh data still there in RAM, and will stay there until another piece of information comes along and replaces the old mesh data?

I know that files on a hard drive work this way, but I'm not sure if RAM is the same way.

Last edited 2011


Yasha(Posted 2011) [#6]
In other words, if you deleted a mesh, isn't the mesh data still there in RAM, and will stay there until another piece of information comes along and replaces the old mesh data?


In practice, usually yes (simple commands like EntityX will usually "work" on any valid memory address). But don't ever rely on this behaviour, because the memory allocator is free to do whatever it wants with space that it thinks isn't in use.

So in answer to this:

Ok, so how do you track the memory use ?


You don't, unless you;re using a system that has some kind of runtime ability to manage memory use. The only figure you can get is how much the system has made available to the program; what the program does with that space is its own business. So that allocated space probably won't go down until something's sure that the program isn't still using it - and that it's worth bothering the program by messing with its space currently in use.

Anyway, you really don't need to go looking for memory leaks in the core command set. Even if they hadn't been in successful commercial use for the last ten years, Mark would have checked these things with the proper debug tools before releasing Blitz3D.


RemiD(Posted 2011) [#7]
Ok, so i can keep coding this way and i only have to use FreeEntity, FreeTexture, FreeImage, FreeSound, FreeFont and Blitz3d manages everything.

That's good for me. I just wanted to be sure i was doing it correctly.

Thanks,