Memory fragmentation & garbage collection
Amir Shoval -- amirs@ncc.co.il Monday, March 31, 1997 Environment: Win 95, VC4.2b Hello, I've written a kind of network monitoring application. This application should be active for a long time, so I wanted to check that I'm not consuming a lot of memory over time. I'm quite sure I have the right delete for every new, and that the delete occurs not too long after the new. My question can be separated into two: 1) Can memory fragmentation (because of many 'new's and 'delete's of relatively small objects) cause consuming a lot of memory? 2) If the answer to the above is YES, I know how to prevent fragmentation caused by objects created from my classes, but what about objects created from MFC classes? For example CString: It's variable part (actually the string) is allocated on the default heap, so if I have many CString objects, they probably increase fragmentation. How can I handle this situation? Any other general advise about memory fragmentation & garbage collecting would be appreciated. 10x, Amir
Daniel W. Levi -- DLevi@hworks.com Tuesday, April 01, 1997 [Mini-digest: 2 responses] Amir, Yes, programs that run a long time can fragment memory badly, and this will affect the performance eventually. Figuring out the actual impact can be very difficult. If you can use STL (the standard template library), it will help avoid fragmentation. It uses some really slick memory allocation techniques. I think CString tries to avoid fragmentation also, by using minimum string sizes and extending strings by a fixed amount when they need to grow. I'm not sure how well it works. Here's a trick: try to make all the structures you new/delete the same size, so memory returned to the heap is always the right size. Of course, this is rarely possible. Another trick is to use the stack whenever possible, i.e. use func() { someclass a; ... } instead of func() { someclass *a = new someclass; ... // allocate something here that lives beyond the function ... delete a; } Question for everybody in general: is there heap analysis tool that will check fragmentation of the heap? Dan Levi dlevi@hworks.com ---------- > From: Amir Shoval> To: 'MFC list' > Subject: Memory fragmentation & garbage collection > Date: Monday, March 31, 1997 12:33 AM > > Environment: Win 95, VC4.2b > > Hello, > > I've written a kind of network monitoring application. This application > should > be active for a long time, so I wanted to check that I'm not consuming a > lot > of memory over time. > > I'm quite sure I have the right delete for every new, and that the > delete occurs > not too long after the new. My question can be separated into two: > > 1) Can memory fragmentation (because of many 'new's and 'delete's of > relatively small objects) cause consuming a lot of memory? > > 2) If the answer to the above is YES, I know how to prevent > fragmentation > caused by objects created from my classes, but what about objects > created > from MFC classes? For example CString: It's variable part (actually the > string) > is allocated on the default heap, so if I have many CString objects, > they > probably increase fragmentation. How can I handle this situation? > > Any other general advise about memory fragmentation & garbage collecting > would be appreciated. > > 10x, > Amir -----From: "Poul A. Costinsky" > From: Amir Shoval > Environment: Win 95, VC4.2b > Hello, > 1) Can memory fragmentation (because of many 'new's and 'delete's of > relatively small objects) cause consuming a lot of memory? Not only it can, but very probably will. > 2) If the answer to the above is YES, I know how to prevent fragmentation > caused by objects created from my classes, but what about objects > created from MFC classes? > For example CString: It's variable part (actually the string) > is allocated on the default heap, so if I have many CString objects, > they probably increase fragmentation. How can I handle this situation? If you know how to fight a fragmentation -:), the answer is simple: don't use CStrings in your long-term objects. You should also call defragmentation routines sometimes. > Any other general advise about memory fragmentation & garbage collecting > would be appreciated. In Win 95 you can use local memory heaps: one for each size of the object or category of the classes. Look at my home page for more details. > 10x, B'vakasha. ---------- Hope this helps. Regards, Poul. ("`-''-/").___..--''"`-._ ~~~~~~~~~~Poul A. Costinsky~~~~~~~~~~ (`6_ 6 ) `-. ( ).`-.__.`) Poul@wizsoft.com.NOSPAM.PLEASE (_Y_.)' ._ ) `._ `. ``-..-' _..`--'_..-_/ /--'_.' ,' (il).-'' (li).' ((!.- http://www.wizsoft.com/~Poul ==========Disclaimer:All my words are my own.==========
Barry Tannenbaum -- barry@dddv.com Tuesday, April 01, 1997 At 08:33 AM 3/31/1997 +0300, you wrote: > Environment: Win 95, VC4.2b > > I've written a kind of network monitoring application. This application should > be active for a long time, so I wanted to check that I'm not consuming a lot > of memory over time. > > I'm quite sure I have the right delete for every new, and that the delete occurs > not too long after the new. My question can be separated into two: > > 1) Can memory fragmentation (because of many 'new's and 'delete's of relatively > small objects) cause consuming a lot of memory? Of course. But unless you've got a pathalogical case, it should tend to stabilize over time. There used to be a requirement that you call _heapmin() to coalese memory, but that seems to have gone away with MSVC 4.0. Check out the documentation on free(). > 2) If the answer to the above is YES, I know how to prevent fragmentation > caused by objects created from my classes, but what about objects created > from MFC classes? For example CString: It's variable part (actually the string) > is allocated on the default heap, so if I have many CString objects, they > probably increase fragmentation. How can I handle this situation? If you use your own heaps for your classes and reserve the default heap for CString, you'll probably minimize fragmentation. - Barry -------------------------------------------------------------------------------- 3DV Technology, Inc Phone: (603) 595-2200 X228 410 Amherst St., Suite 150 Fax: (603) 595-2228 Nashua, NH 03063 Net: barry@dddv.com
Mike Blaszczak -- mikeblas@nwlink.com Tuesday, April 01, 1997 [Mini-digest: 3 responses] At 11:28 4/1/97 -0500, Daniel W. Levi wrote: >If you can use STL (the standard template library), it will help avoid >fragmentation. It uses some really slick memory allocation techniques. The UnStandard Class Library defines behaviour, not an implementation. As such, there's no way to make a blanket claim that "[the STL] uses some really slick memory allocation techniques". The UnStadard Class Library _does_ dictate that most classes in the library are templatized around allocators, hwich allows you to implement and specify your own special-case memory management routines. If you can craft an algorithm that is closely optimized to your access patterns and data, you can increase your application's efficiency. As-is, though, the UnStandard Class Library implementation that ships with VC++ 5.0 and the one that ships with VC++ 4.2 both end up simply calling the regular C Runtime library implementations of operator new() and operator delete()--which are pretty good for the general case and have some optimizations for small block allocations. But it's pretty easy to see that the UnStandard Class Library implementations that Microsoft ships aren't doing anything slick at all: they're just calling the runtime routines. Quite the opposite is true, in my experience: the VC++ 5.0 implementation of some of the string stream classes, for example, are miserably inefficient when it comes to memory management. Maybe if you buy a different UnStandard Class Library implementation, like Rogue Wave's, you can find some other behaviour. But that just goes to underscore the fact that the UnStandard specifies behaviour, not an implementation. >I think CString tries to avoid fragmentation also, by using minimum string >sizes and extending strings by a fixed amount when they need to grow. I'm >not sure how well it works. CString uses minimum string sizes, but does not extend strings by a fixed amount when they need to grow; it just extends them by the amount that they need to grow. It's really not doing anything any differently than the basic_string implementation in the Unstandard Class Library that ships with VC++ 5.0, for example. (So, I guess if you think the USCL is slick, you'll necessarily think that CString is slick, since they're doin' the same thing.) >Here's a trick: try to make all the structures you new/delete the same >size, so memory returned to the heap is always the right size. Of course, >this is rarely possible. In fact, in an MFC application, it's nearly never possible. MFC is doing its own allocations and deallocations, which means that your efforts are for naught. MFC will end up allocating and freeing temporary objects, or collection marker objects, or a buffer for an API call, and that'll disrupt your scheme. >Question for everybody in general: is there heap analysis tool that will >check fragmentation of the heap? You can write your own using the _heapwalk() function provided by the CRTL. I think heap fragmentation is really not worth worrying about, though, aside from a very few specific (and pretty esoteric) cases. If you're worried about some objects being allocated and freed very quickly, your best bet is to override operator new() and operator delete() for the class that implements those objects. Without hearing any details of Amir's application, it's hard to tell if he's having problems with fragmentation or not: this might be a wild goose chase. As Poul points out, you can call _heapmin(). But there's no real reason to avoid CString (or favor basic_string, or avoid basic_string); it's not going to fragment memory any more heavily than dynamically allocating your own array of TCHARs if the string content isn't changing a lot. If it the content _is_ changing heavily, the effects of CString's reallocations can be minimized by preallocation while the effects of basic_string's can be minimized by replacing the allocator implementation. >In Win 95 you can use local memory heaps: one for each size of the object >or category of the classes. Look at my home page for more details. Actually, private heaps are available under WinNT, as well. They're not unique to Windows 95. .B ekiM Crotch Rocket / Full-Body Rocket / Trip Report Central! 95 Honda VFR-750F / 94 Mazda RX-7 / http://www.nwlink.com/~mikeblas/ Less work, more hockey! These words are my own - I do not speak on behalf of Microsoft. -----From: Amir ShovalTo continue the discussion, I am using fixed heaps for 3 of my classes which are allocated (and freed) dynamically in large quantities.=20 The second answer talks about 'defragmentation routines'. What are these? Can I defragment the default heap somehow? >From both answers it seems MFC is NOT suitable for writing a continuously running application. Is it true (Mike B.)? Where can I find MFC related 'tips & tricks' for better memory management? 10x again, Amir >---------- >From: Daniel W. Levi[SMTP:DLevi@hworks.com] >Sent: =E9=E5=ED =F9=EC=E9=F9=E9 01 =E0=F4=F8=E9=EC 1997 19:28 >To: mfc-l@netcom.com >Subject: Re: Memory fragmentation & garbage collection > >[Mini-digest: 2 responses] > >Amir, > >Yes, programs that run a long time can fragment memory badly, and this = will >affect the performance eventually. Figuring out the actual impact can = be >very difficult. > >If you can use STL (the standard template library), it will help avoid >fragmentation. It uses some really slick memory allocation techniques. = =20 > >I think CString tries to avoid fragmentation also, by using minimum = string >sizes and extending strings by a fixed amount when they need to grow. = I'm >not sure how well it works. > >Here's a trick: try to make all the structures you new/delete the same >size, so memory returned to the heap is always the right size. Of = course, >this is rarely possible. > >Another trick is to use the stack whenever possible, i.e. use > >func() >{ > someclass a; > ... >} > >instead of > >func() >{ > someclass *a =3D new someclass; > ... > // allocate something here that lives beyond the function > ... > delete a; >} > > > > >Question for everybody in general: is there heap analysis tool that = will >check fragmentation of the heap? > >Dan Levi >dlevi@hworks.com > >---------- >> From: Amir Shoval >> To: 'MFC list' >> Subject: Memory fragmentation & garbage collection >> Date: Monday, March 31, 1997 12:33 AM >>=20 >> Environment: Win 95, VC4.2b >>=20 >> Hello, >>=20 >> I've written a kind of network monitoring application. This = application >> should >> be active for a long time, so I wanted to check that I'm not = consuming a >> lot >> of memory over time. >>=20 >> I'm quite sure I have the right delete for every new, and that the >> delete occurs >> not too long after the new. My question can be separated into two: >>=20 >> 1) Can memory fragmentation (because of many 'new's and 'delete's of >> relatively small objects) cause consuming a lot of memory? >>=20 >> 2) If the answer to the above is YES, I know how to prevent >> fragmentation=20 >> caused by objects created from my classes, but what about objects >> created >> from MFC classes? For example CString: It's variable part (actually = the >> string) >> is allocated on the default heap, so if I have many CString objects, >> they >> probably increase fragmentation. How can I handle this situation? >>=20 >> Any other general advise about memory fragmentation & garbage = collecting >> would be appreciated. >>=20 >> 10x, >> Amir >-----From: "Poul A. Costinsky" > >> From: Amir Shoval >> Environment: Win 95, VC4.2b >> Hello, >> 1) Can memory fragmentation (because of many 'new's and 'delete's of >> relatively small objects) cause consuming a lot of memory? > >Not only it can, but very probably will. > >> 2) If the answer to the above is YES, I know how to prevent = fragmentation > >> caused by objects created from my classes, but what about objects >> created from MFC classes?=20 >> For example CString: It's variable part (actually the string) >> is allocated on the default heap, so if I have many CString objects, >> they probably increase fragmentation. How can I handle this = situation? > >If you know how to fight a fragmentation -:), the answer is simple: >don't use CStrings in your long-term objects. You should also call >defragmentation >routines sometimes. > >> Any other general advise about memory fragmentation & garbage = collecting >> would be appreciated. > >In Win 95 you can use local memory heaps: one for each size of the = object >or category of the classes. Look at my home page for more details. > >> 10x, >B'vakasha. >---------- > >Hope this helps. >Regards, >Poul. > ("`-''-/").___..--''"`-._ ~~~~~~~~~~Poul A. Costinsky~~~~~~~~~~ > (`6_ 6 ) `-. ( ).`-.__.`) = Poul@wizsoft.com.NOSPAM.PLEASE > (_Y_.)' ._ ) `._ `. ``-..-' > _..`--'_..-_/ /--'_.' ,' > (il).-'' (li).' ((!.- http://www.wizsoft.com/~Poul >=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DDisclaimer:All my words are my = own.=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > > > -----From: Alex Fok Amir Shoval wrote: > > Environment: Win 95, VC4.2b > > Hello, > > I've written a kind of network monitoring application. This application > should > be active for a long time, so I wanted to check that I'm not consuming a > lot > of memory over time. > > I'm quite sure I have the right delete for every new, and that the > delete occurs > not too long after the new. My question can be separated into two: > > 1) Can memory fragmentation (because of many 'new's and 'delete's of > relatively small objects) cause consuming a lot of memory? > > 2) If the answer to the above is YES, I know how to prevent > fragmentation > caused by objects created from my classes, but what about objects > created > from MFC classes? For example CString: It's variable part (actually the > string) > is allocated on the default heap, so if I have many CString objects, > they > probably increase fragmentation. How can I handle this situation? > > Any other general advise about memory fragmentation & garbage collecting > would be appreciated. > > 10x, > Amir -- I think that memory fragmentation & garbage collection belong to memory management area. Is memory management a job of Application? I think that good designed operating system should do garbage collection itself. I think Unix, for example, does. Is Win95/Win NT good designed operating systems from this point of view? Has anyone tested it? ____________________________________________________________ | | | | Alexander Fok | E-mail: alexp@sharnoa.co.il | | Software Engineer | Office: +972-7-6285058 | | | Fax: +972-7-6277859 | | Xtrol (Sharnoa) | Home: +972-7-6271886 | | Corporation Israel | WWW : http://www.cs.bgu.ac.il/~alexf | |_____________________|______________________________________|
Mike Blaszczak -- mikeblas@nwlink.com Wednesday, April 02, 1997 [Mini-digest: 2 responses] >-----From: Amir Shoval>To continue the discussion, I am using fixed heaps for 3 of my classes >which are allocated (and freed) dynamically in large quantities. >The second answer talks about 'defragmentation routines'. What are >these? They are routines that coalesce free space in the heap. They can be expensive to call, so you can actually _hurt_ performance by calling too often. If you're using Win32 SDK heaps that you've gotten from the ::HeapAlloc() API, you can call the ::HeapCompact() API to compact the heap. If you're using the C Runtime's heap, you can call _heapmin(). >Can I defragment the default heap somehow? If you mean the default Win32 heap for your process, you can get a handle to it by calling the ::GetProcessHeap() API. Then, call the ::HeapCompact() API on the API. >From both answers it seems MFC is NOT suitable for writing a >continuously running application. Is it true (Mike B.)? No, it isn't. MFC does lots of work for you, and makes many things simpler, but it doesn't excuse you from thinking about your application. If you know your application is going to run forever, you need to worry about some issues. This is one of the most important. That you need to worry about certain issues when writing software is true no matter what tool or library you do (or don't!) use. .B ekiM http://www.nwlink.com/~mikeblas/ These words are my own. I do not speak on behalf of Microsoft. One is too many and a million is not enough. -----From: Luc-Eric Rousseau At 08:20 PM 4/1/97 -0800, you wrote: >>Question for everybody in general: is there heap analysis tool that will >>check fragmentation of the heap? > >You can write your own using the _heapwalk() function provided by the CRTL. > >I think heap fragmentation is really not worth worrying about, though, aside >from a very few specific (and pretty esoteric) cases. If you're worried about >some objects being allocated and freed very quickly, your best bet is to >override operator new() and operator delete() for the class that implements >those objects. Our tax income program's heap (made with VC 1.5x) just grows and grows and grows through the day. (No, we pass the thing through Bound Checker and there are not memory leaks). I can't understand how you can say that heap fragmentation could not be a problem with a program that runs all day. We probably have 500 CString allocated at any one time. And as users open and close files, the strings get freed and possibly realocated. Large memory blocks get fragmentated into smaller ones and after a while the heap manager doesn't seem to be able to find more. Maybe a heap manager replacement (like SmartHeap) could help. >Without hearing any details of Amir's application, it's hard to tell if he's >having problems with fragmentation or not: this might be a wild goose chase. > >As Poul points out, you can call _heapmin(). But there's no real reason to >avoid CString (or favor basic_string, or avoid basic_string); it's not going >to fragment memory any more heavily than dynamically allocating your own >array of TCHARs if the string content isn't changing a lot. If it the >content _is_ changing heavily, the effects of CString's reallocations can >be minimized by preallocation while the effects of basic_string's can be >minimized by replacing the allocator implementation. Does heapmin() actually do something? It's my expererience that calling it doesn't do much expect in very extreme cases.
Marion Nalepa -- mnalepa@ontime.com Thursday, April 03, 1997 [Mini-digest: 2 responses] >If you know your application is going to run forever, you need to >worry about some issues. This is one of the most important. Are the relevant issues regarding forever-running MFC programs documented anywhere? -----From: "Adam Miller"I wouldn't tend to worry about fragmentation in a typical GUI application. However, if there is need it makes sense to attempt to organize memory. OS paging is something that always concerns me. If I can help the OS out by organizing memory such that frequently hit addresses exist within similiar pages, that only lessens the burden on the paging the OS would do. For instance, if you need to maintain a large collection of objects of your own, it would probaly improve things to overide new/delete and use the Heap API's. Especially if you need to access these objects often. It would help the OS out by allowing it to organize those memory pages in a contiguous fashion. The other approach typically taken is to use the memory pool method. A mem pool allocator will typically round up the requested size to some power of 2. It will maintain each of these pools seperately. This method could improve performance when using many short-lived, small allocations or using a lot of asynch I/O and maintaing buffers for reads and writes. I've had success with using the OSE class library in an MFC app. OSE has template collection classes, a mem-pool allocator, string classes, object reference counting and lots of other neat stuff. Almost all objects are allocated out of memory pools. I find it more stable and usable than STL currently, and it is portable across WIN32 and Unix based OS's. The compilation/installation procedure is a little tough going but it does work nicely. Source is provided and the license is free for commercial use. OSE is at http://www.dscpl.com.au/ose.html Adam Miller royalblue technologies
Mike Blaszczak -- mikeblas@nwlink.com Thursday, April 03, 1997 [Mini-digest: 2 responses] >-----From: Luc-Eric Rousseau>Our tax income program's heap (made with VC 1.5x) just grows and grows and >grows through the day. (No, we pass the thing through Bound Checker and >there are not memory leaks). Just because something gets through BoundsChecker cleanly doesn't mean that it doesn't have leaks. >I can't understand how you can say that heap fragmentation could not be a >problem with a program that runs all day. I can't understand how you can put words into my mouth. I was answering someone who was using a version of Visual C++ and MFC and the C Runtimes for Win32, not for Win16. You're using Win16, while the fellow I was answering was using Win32. >Does heapmin() actually do something? It's my expererience that calling it >doesn't do much expect in very extreme cases. Look at the sourcecode and figure it out yourself. If I were to answer you, you'll just put words into my mouth and make the answer sound the way you want it to, anyway. Again. So I'd rather save myself the time and frustration. .B ekiM http://www.nwlink.com/~mikeblas/ These words are my own. I do not speak on behalf of Microsoft. One is too many and a million is not enough. -----From: Olivier PLANCHON Hello , as a general contribution to the question, I generated a 'heap simulator' and tryed some simulations : method : ======= 1st allocate N>1000 contiguous blocks of data. the size of one block is random from 1 to 1000 2nd randomly delete one of them and allocate a new one (of != size) result : ======= the situation quickly stabilize to an equilibrium : 1) number of fragments = N/2 2) total amount of memory used < 1.2 * total size of data discussion : =========== 1) a new data block is always allocated closed to a previous one, never in the middle of a free memory segment, so the worst we can get is 1 heap block for 2 data blocks. This worst situation is quickly reached. 2) at the equilibrium, the median size of a fragment of free memory in the heap is less than the median size of a new element. If it was'nt, a new element has a probability of 50% to fit in half of the holes, so the mean size of a free fragment has>50% to decrease. conclusion : =========== The real problem whith memory fragmentation is not the amount of memory because it will never spoil a large amount of space. The problem is the number of fragments : they tend to = half of the number of data blocks. If the number of objects (not their size !) your app have to handle at the same time is about twice or more the number of heap fragments the heap manager can support(*), you will have to look for garbadge collecting. Elsewhere, just don't care. (*) I just don't know this. at least 10000 per heap ? (Is it, Mike B. ?) >>> From: Amir Shoval >>> To: 'MFC list' >>> Subject: Memory fragmentation & garbage collection >>> Date: Monday, March 31, 1997 12:33 AM >>>=20 >>> Environment: Win 95, VC4.2b >>>=20 >>> Hello, >>>=20 >>> I've written a kind of network monitoring application. This = >application >>> should >>> be active for a long time, so I wanted to check that I'm not = >consuming a >>> lot >>> of memory over time. >>>=20 >>> I'm quite sure I have the right delete for every new, and that the >>> delete occurs >>> not too long after the new. My question can be separated into two: >>>=20 >>> 1) Can memory fragmentation (because of many 'new's and 'delete's of >>> relatively small objects) cause consuming a lot of memory? >>>=20 >>> 2) If the answer to the above is YES, I know how to prevent >>> fragmentation=20 >>> caused by objects created from my classes, but what about objects >>> created >>> from MFC classes? For example CString: It's variable part (actually = >the >>> string) >>> is allocated on the default heap, so if I have many CString objects, >>> they >>> probably increase fragmentation. How can I handle this situation? >>>=20 >>> Any other general advise about memory fragmentation & garbage = >collecting >>> would be appreciated. >>>=20 >>> 10x, >>> Amir --------------------------------------- Olivier PLANCHON, ORSTOM, BP 1386 Dakar tel(221) 32 34 80 fax (221) 32 43 07 e-mail Olivier.Planchon@orstom.sn
Become an MFC-L member | Вернуться в корень Архива |