deleting types
BlitzMax Forums/BlitzMax Programming/deleting types
| ||
How do you delete a user defined type once it is created? The docs show the command 'delete' but it says its for future expansion. |
| ||
Set it to null and call flushmem. *EDIT* a better way is to implement your own free() function or method to free it, that way you can clear up any child types before freeing the main one. |
| ||
Hi Perturbatio, thanks for the input. Do you have any example 'free()' methods? I've tried using self = null but that doesnt work |
| ||
Local i:MyType = New MyType '' Create new MyType i = Null '' Nullify it FlushMem '' Free all unreferenced objects |
| ||
what about internally nullifying it? i.free() |
| ||
what about internally nullifying it You cannot and should not do that. Objects will be freed automatically on the next call to FlushMem as soon as there are no more references to the object. Follow Noel's example. |
| ||
Can you explain why I 'can not and should not?' I want to be able to have the original type deleted as I delete each item in a list. i.e. Method freeMedPak() if self.quiz:TMedPakQuiz <> null For Local n:TMedPakQuiz = EachIn self.quizList:TList n.free() next end if End Method This would loop through the list and n.free() would preferably cause the link in the list to be deleted as well as the type instance |
| ||
Can you explain why I 'can not and should not?' Because if BlitzMAX tries to access any fields of an object after that object has been freed manually, it will either bomb out with an error, or cause some very odd things to happen. Regarding your code, just do this: Method freeMedPak() if quiz then quizList.Clear() FlushMem End Method That will delete all the items from the list, and assuming there are no other references to those items, they will also be freed during the call to FlushMem. That is the great thing about BlitzMAX' memory management - it saves a lot of effort. Edit: To clarify about memory management. Unless you are dealing with other external APIs, you can effectively forget about it. Just call FlushMem: (1) On a regular basis during the normal game (usually once during each game loop for example) (2) After operations where a lot of memory has been allocated (eg. loading a game level, or after reading the contents of a file line by line). |
| ||
Example of objects being deleted: |
| ||
optimize ListAddLast(TypeList,Self) wutg TypeList.addlast (self) :) (why not fully OO when start to use it ;-) and this is not needed: TSomeType.TypeList.Remove(tst) You can use TypeList.remove (tst) instead as TypeList and Function are member of the same type scope. PS: Flushmem within function is very evil and a guarantee for memory leaks. So you should avoid to use if at other places then your main loop if the function will be called more then a single time (initialization / clean up of levels or application) |
| ||
PS: Flushmem within function is very evil and a guarantee for memory leaks. So you should avoid to use if at other places then your main loop if the function will be called more then a single time (initialization / clean up of levels or application) Are you sure about that? According to the docs, FlushMem only frees objects allocated in the same scope or in deeper scopes than the FlushMem call itself. This means that you can use FlushMem in methods or functions, just remember that it won't free objects allocated outside of the function / method - to do that you have to call FlushMem at the global scope. |
| ||
Yepp but the GC itself needs some memory with every "instance" you create of it. At least in the last versions it was this way. And the "higher scope" flushmem did not free the memory allocated by "function flushmem" ... might have checked but haven't seen any note on a change in the memory management system ... |
| ||
Using Stuart's code, why is the MemAlloced() growing? I am getting after 1000 iterations: memory alloced start: 5606 memory alloced end: 45754 I am loading in questions and answers in the app I am working on, and in 100 iterations the MemAlloced() = 128mb :/ Type TSomeType Global TypeList:TList Global Count:Int Field Param:Int Method New() If TypeList = Null Then TypeList = New TList ListAddLast(TypeList,Self) Count :+ 1 End Method Method Delete() Count :- 1 End Method Function Create:TSomeType(Param:Int) Local tst:TSomeType = New TSomeType tst.Param = Param Return tst End Function Function Update() For Local tst:TSomeType = EachIn TSomeType.TypeList TSomeType.TypeList.Remove(tst) FlushMem Print "Number of objects: "+TSomeType.TypeList.Count() Next End Function End Type Print "memory alloced start: "+MemAlloced() For Local i:Int = 0 To 1000 TSomeType.Create(i) Next TSomeType.Update() Print "memory alloced end: "+MemAlloced() |
| ||
Here is another example of the apparent 'memory leaking' based on code posted in the radomizing a list topic. My results: ***************************************************************** Memory allocated after object creation: 289870 Memory allocated after randomizing: 1110206 ***************************************************************** is the memory leaking? Why is MemAlloced() increasing? Since the objects and lists are created... why is shuffling the lists around causing the memory to grow significantly? ' randomize a list of items in a list Global list:TList=CreateList() Global memory1:Int Global memory2:Int Type foodtype Field name$ Field price# Method Add(n$,p#) Local f:foodtype=New foodtype f.name$=n$ ; f.price=p ListAddLast list,f EndMethod Method ShowList() Print "----------------------" For Local f:foodtype=EachIn list Print f.name$+" - "+f.price Next EndMethod Method RandList(numtimes=3) For Local n=1 To numtimes For Local f:foodtype=EachIn list If Rnd()>0.3 ListRemove list,f ListAddLast list,f FlushMem EndIf Next Next EndMethod End Type SeedRnd MilliSecs() For Local i = 0 To 1000 Local f:foodtype f=New foodtype f.Add "pizza",2.50 f.Add "sausage",0.75 f.Add "pie",1.53 f.Add "onion",0.21 f.Add "soup",0.97 f.Add "crisps",0.29 Next memory1 = MemAlloced() f.ShowList Print "~nrandom ..." f.RandList(1) memory2 = MemAlloced() f.ShowList Print "*****************************************************************" Print "Memory allocated after object creation: "+memory1 Print "Memory allocated after randomizing: "+memory2 Print "*****************************************************************" DebugStop End |
| ||
because you create memory leaks with flushmem outside the base scope NEVER use flushmem outside the "main loop" level (base scope level of app) or you will have memory leaks. This is due to memory that is used by GC to clean up. |