From: Chuck Remes Date: 2010-01-14T00:55:02+09:00 Subject: Re: WIN32OLE memory leaks On Jan 12, 2010, at 4:10 PM, Luis Lavena wrote: > On Jan 12, 6:19 pm, Chuck Remes wrote: >> In my ruby code I am making a call out to a COM object that is >> returning an array of objects. I extract some information from these >> objects and then request a new batch to do the same work all over >> again. >> >> Even though I am clearing the received array out, my program slowly >> leaks memory until it hits its limit (around 1.4 GB on Windows) and >> dies. >> >> I have tried adding my_object.ole_free calls everywhere, but that has >> not helped at all. I've looked through the archives (back to 2004) >> and >> saw that this was a common issue years ago. I had hoped it would be >> fixed by now. >> >> Does anyone have any suggestions on how to force these unused objects >> to get GC'ed? This program needs to run a long time so a memory leak >> is absolutely fatal. > > Please include exact and complete version of Ruby you're using (ruby - > v) and under which Windows flavor. > > Also, if this can be reproducible with any COM object, include a > sample script for us to reproduce in other Windows version and Ruby > version combinations. Sorry for not providing more details. I actually thought this might be a "known" issue. Here's some code. This is running against 1.8.6-p383 (from rubyinstaller.org) on Windows XP SP3 plus all the latest patches (Windows Update runs weekly). def register_callbacks event.on_event('DataResolved') do |collection, error| save collection unless error @flag1 = false end end def save collection collection.each do |data| doc = { 'field1' => data.Property1.to_i, 'field2' => data.Property2.to_f, 'field3' => data.Property3 } @mongo_collection.insert doc data.ole_free end collection.ole_free end def request_data start_date, end_date @start_date = start_date @end_date = end_date @flag1 = true request = @com.CreateDataRequest range_start_method = request.ole_method_help 'RangeStart' range_end_method = request.ole_method_help 'RangeEnd' request._setproperty range_start_method.dispid, [@start_date], [VT_DATE] request._setproperty range_end_method.dispid, [@end_date], [VT_DATE] @com.RequestData request end I have a method that makes a function call on the COM object (#request_data). When the function has data to return, it generates a "DataResolved" event which triggers my callback which was registered once at the beginning of execution. The callback calls #save and loops through the collection and pulls some properties into a hash which then gets inserted into mongodb. When the collection is exhausted, I go back to #request_data and make another call on the COM object to request the next batch. The collection returned is usually around 30MB. I don't leak all 30MB each time through; it leaks a big percentage of it though (30 to 50%). When Task Manager tells me the ruby.exe process is taking up around 1.4GB, the process just exits. Unfortunately this application is not available to the general public so I can't provide a script for someone to independently verify this. :( cr