How do I free this memory?

Everything else that doesn't fall into one of the other PB categories.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

How do I free this memory?

Post by pdwyer »

In the code below:
At the first messagebox the mem usage of the exe in task manager is about 6mb. I hit ok and it jumps to 26mb (assumably due to the space() usage and the string). When I click the second ok it drops by 10mb to 16mb due to cleaning up the loadstring variable.

How do I get the app back to 6mb?

Code: Select all

MessageRequester("first","")
loadstring.s = Space(10000000)
MessageRequester("before","")
loadstring = ""
MessageRequester("after","")
I suspected a leak when I noticed this but if I put space() in a loop it doesn't leak any more than (haven't tested if it's the first or the largest)
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

Hi,

From codearchiv.

Code: Select all

Procedure FreeString_ASM(*TheString) 
  !MOV edx, 0 
  !LEA ecx, [p.p_TheString] 
  !CALL SYS_FastAllocateStringFree 
  ProcedureReturn 
EndProcedure
Best regards

Wolf
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Either you didn't understand the question or I'm not understanding the answer :D

When the string "Loadstring" is set to "" then the 10mb of spaces assigned to it are cleaned up and the memory usage drops. There was 10mb of memory also used somehow "under the hood" from using the space() command.

If I have freed up "loadstring" already, it's that other bit. Perhaps if I do the space() command in a fucntion then it will clean up when it goes out of scope :?:

I tried using your function anyway

Code: Select all

Procedure FreeString_ASM(*TheString) 
  !MOV edx, 0 
  !LEA ecx, [p.p_TheString] 
  !CALL SYS_FastAllocateStringFree 
  ProcedureReturn 
EndProcedure 

MessageRequester("first","")

loadstring.s = Space(10000000)

MessageRequester("before","")

FreeString_ASM(@loadstring)

MessageRequester("after","")
but the effect is the same
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

Hi mate,

I am no expert on these sorts of things, but I had thought (usually a dangerous event).

Is it possible that the memory was freed but windows has not got around to or bothered to release the memory yet? There is something nagging at the back of my mind (and not one of the females in the house!) that suggests this is sometimes the case.

But as I say, I know next to doodly squat to treat this accordingly.
Dare2 cut down to size
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

hmmm,

It's not a time thing, with the msgbox open I can just let it sit there for a while, and only the 10mb is cleaned from the string and not whatever happened with the space().

There was an API and I can't for the life of me remember what it was, that shrinks the mem/virtual mem used by a process to only what it was actually using and paged the rest out. It was handy if you wanted to create a little quiet agent that was really low on resouce usage. perhaps that could do come cleanup then.

this seems quite odd though. It holds onto the largest allocation of space. in the code below it goes as high as 200mb slowly but will not free up the last 100mb

Code: Select all


MessageRequester("first","")

For i = 1 To 10
    loadstring.s = Space(10000000 * i)
    Delay(2000)
    loadstring = ""
Next
MessageRequester("before",Str(Len(loadstring)))

loadstring = ""

MessageRequester("after","")

Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

PB uses an internal buffer to manipulate the strings.

Perhaps if you've caused it to be 10MB then it may not have been freed (i.e. it stays at the largest used size).

But that's pure speculation, you'd need to get one of the team to confirm whether that's what happens.
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Fr34k solution here: Freeing Strings
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Forget about creative ways to free the string, it won't work.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

I have had many problems with freeing memory and clearing buffers. Perhaps t should be a new request in the next version of PB? 8)
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

@Psychophanta: I don't think this is the same as I'm not trying to free the memory of a string, I'm trying to free some temp memory used by space()

@Trond: Could you elaborate a little?

It looks kind of ugly from task manager.

I wonder if there's any other functions like space() that do this :?

I suppose there's one way to find out if it's actually in use or not... use it all and see what happens :twisted:
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Yes, PB use an internal buffer to manipulate quickly the strings. It is always set to the larger size you use in a string function (for now, it nevers shrink for performance reason, but we planned to add a counter and resize it after a few smaller calls).
case
Enthusiast
Enthusiast
Posts: 141
Joined: Thu Aug 07, 2003 11:09 am

Post by case »

if this have a performance hit why not adding a command for us to free it ourself when we don't need perfomance or just after we use a really large string. maybe a flushstringbuffer() command ? as for a normaly sized string this is not really important that the memory get still ocuped for the buffer as long as the program run.

better imho than a counter so we can control when we wan't to clear it :) as a counter ca in fact release it in a loop when we need performance more:)
Last edited by case on Mon Jan 21, 2008 2:17 pm, edited 1 time in total.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Thanks Fred,

2 Questions:

1: Is there any workaround? I notice that doing this in a function doesn't clean up with fuction returns.

2: Are there any other functions built in to PB that could potentially use large chunks of memory and not return them till app closure? Using several of them could add up.

Cheers
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

Edit 2: fixed code I think.

Here's a hack to resize the internal string buffer, Windows only and needs some assembly. I don't know whether the length of the buffer is set in characters or bytes (which will be important for Unicode) so use at your own risk.

Code: Select all

!extrn _PB_StringBaseSize
!extrn _PB_StringHeap

Define.l string_base
Define.l string_position
Define.l string_heap
Define.l string_size

Gosub GetStringStuff
MessageRequester("Info", "Base=$"+Hex(string_base)+Chr(10)+"Position=$"+Hex(string_position))

foo.s = Space(10000000)
Gosub GetStringStuff
MessageRequester("Info", "Base=$"+Hex(string_base)+Chr(10)+"Position=$"+Hex(string_position))

foo.s = Space(10)
Gosub GetStringStuff
MessageRequester("Info", "Base=$"+Hex(string_base)+Chr(10)+"Position=$"+Hex(string_position))

heap_size.l = HeapSize_(string_heap, 0, string_base)
MessageRequester("Info", "HeapSize="+Str(heap_size))

;- Reset the string size
#HEAP_ZERO_MEMORY = 8
string_base = HeapReAlloc_(string_heap, #HEAP_ZERO_MEMORY, string_base, 16384)
string_size = 16384
EnableASM
    mov eax, dword [v_string_base]
    mov [_PB_StringBase], eax

    mov eax, dword [v_string_size]
    mov [_PB_StringBaseSize], eax
DisableASM

Gosub GetStringStuff
heap_size.l = HeapSize_(string_heap, 0, string_base)
MessageRequester("Info", "HeapSize="+Str(heap_size))

; Little test
foo.s = Space(10)+"blah"
MessageRequester("Test", foo)

; Have we knackered something that caches the length of the heap?
foo.s = Space(10000000)
MessageRequester("Test", "If you got here without a crash, hopefully it worked :)")

End

GetStringStuff:
    EnableASM
    mov eax, dword [_PB_StringBase]
    mov [v_string_base], eax
    mov eax, dword [_PB_StringBasePosition]
    mov [v_string_position], eax
    
    mov eax, dword [_PB_StringHeap]
    mov [v_string_heap], eax
    
    mov eax, dword [_PB_StringBaseSize]
    mov [v_string_size], eax
    
    DisableASM
    Return
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Post Reply