Travis D Warlick Jr wrote the following on 17.07.2007 01:31 :
> dtuttle1 / gmail.com wrote:
>   
>> Hi - I have a memory and cpu-constrained embedded app. There's a long-
>> running loop with a local object (buffer) which eats up memory. A
>> GC.start on every iteration will reclaim it, but that eats the cpu.
>>
>> Is there a way to deallocate the memory used by the temporary objects?
>>
>> file = File.new file_path
>> while buffer = file.read(512)
>>   stream_host_connection.write buffer
>>   stream_host_connection.flush
>>   # GC.start - too expensive
>> end
>>     
>
> Someone please correct me if I'm wrong, but...
>
> You don't need to deallocate buffer every time because it is not getting
> duplicated at the beginning of every iteration -- it is being
> overwritten, so the memory usage for buffer will always stay at 512
> bytes (plus the static overhead for the object).
>
> Deallocating it every time would actually increase CPU usage because you
> would be deleting and recreating the buffer object at the beginning of
> every iteration.
>
> If you're really constrained on memory, you might want to consider
> decreasing the amount that you read at every iteration.  However,
> remember that you increase your CPU usage by the same factor that you
> decrease your memory usage in this case.
>   

Actually, as variable affectation is done by reference and the *content* 
of buffer is originally duplicated by File#read memory usage is not 
likely to change linearly with the value passed to File#read...

You can still play with different values passed to it and expect some 
change of behaviour (ie: depending on the actual amount of memory 
allocated for each read, you may or may not hit a sweat spot in the GC 
heuristics).

My advise would be to do larger reads and GC.start less often:

read_amount = 65536
read_count = 0
loops_between_gcs = 100
while buffer = file.read(read_amount)
  stream_host_connection.write buffer
  stream_host_connection.flush
  GC.start if ((read_count += 1) % loops_between_gcs) == 0
end


But note that if stream_host_connection.flush doesn't actually wait 
until the buffer isn't referenced anymore anywhere in your code (or in 
some other process sitting on the same system as a matter of fact), 
calling GC.start probably won't have any effect.

Lionel