digitalmars.D.learn - Any way to track memory allocations?
- wade Shen (4/4) Feb 24 2009 I'm writing some performance sensitive code (real time processing) for w...
- Jarrett Billingsley (29/31) Feb 24 2009 ich I've tried to minimize the number of memory allocations by using pre...
- BCS (4/13) Feb 24 2009 Someone should make such a GC shell. You could add a BanAlloc(bool) opti...
- Denis Koroskin (2/14) Feb 24 2009 Good idea!
- wade (5/36) Feb 24 2009 Thanks,
- Lutger (11/23) Feb 24 2009 which I've tried to minimize the number of memory allocations by using
- wade (14/40) Feb 24 2009 Thanks again for all the help. I found what the problem was and it wasn...
- Daniel Keep (6/25) Feb 24 2009 Yup.
- Jarrett Billingsley (7/11) Feb 24 2009 You can use "foreach(k; aa)" and "foreach(_, v; aa)".
- Daniel Keep (15/30) Feb 24 2009 True; although I'm one of those people who stays up at night, plotting
- Jarrett Billingsley (2/3) Feb 24 2009 Oh, yes X| .keys and .values of AAs are constructed whenever you use th...
- Sean Kelly (10/26) Feb 25 2009 This has been on my "to do" list forever. One of these days I'll
I'm writing some performance sensitive code (real time processing) for which I've tried to minimize the number of memory allocations by using preallocated objects pools. Unfortunately, during the course of running, it seems that lots of memory is still getting allocated even though all explicit "new" and array slicing operations have been moved out of the main processing loops. As a result the program is quite slow when garbage collection is enabled (but very fast otherwise). Is there a way to track down where memory is being allocated if I'm using phobos? Any recommendations would be appreciated. thanks, wade
Feb 24 2009
On Tue, Feb 24, 2009 at 12:00 PM, wade Shen <swadenator gmail.com> wrote:I'm writing some performance sensitive code (real time processing) for wh=ich I've tried to minimize the number of memory allocations by using preall= ocated objects pools. =A0Unfortunately, during the course of running, it se= ems that lots of memory is still getting allocated even though all explicit= "new" and array slicing operations have been moved out of the main process= ing loops. =A0As a result the program is quite slow when garbage collection= is enabled (but very fast otherwise). Array slicing does not cause the GC to run. It is essentially free, which is a wonderful thing.Is there a way to track down where memory is being allocated if I'm using=phobos? Any recommendations would be appreciated. This is something I have *always* wanted. Unfortunately I don't think it's possible to add such instrumentation without modifying and recompiling Phobos. Even if you're using D2, which uses druntime, there's no such thing. Hm, actually.. If you *are* using D2, you might be able to replace the GC interface with a "debug" interface that just forwards calls to the normal GC. This is a capability druntime inherited from the Tango runtime - the GC is separated from the rest of the standard library and can actually be replaced at link-time. I don't know if D2 links all three parts of druntime into a single library or not, though. Here are some other things that could be causing allocation: - Array appending (~=3D) can cause it; array concatenation (~) is guaranteed to cause it. - Array .dup. - Adding items to associative arrays. - In D2, nested functions/anonymous delegates can allocate memory secretly, unless you're careful and only pass them to "scope" delegate parameters.
Feb 24 2009
Reply to Jarrett,Hm, actually.. If you *are* using D2, you might be able to replace the GC interface with a "debug" interface that just forwards calls to the normal GC. This is a capability druntime inherited from the Tango runtime - the GC is separated from the rest of the standard library and can actually be replaced at link-time. I don't know if D2 links all three parts of druntime into a single library or not, though.Someone should make such a GC shell. You could add a BanAlloc(bool) option that would turn on an assert on any allocation. This could be set and cleared around the RT parts of the code.
Feb 24 2009
On Tue, 24 Feb 2009 20:40:13 +0300, BCS <ao pathlink.com> wrote:Reply to Jarrett,Good idea!Hm, actually.. If you *are* using D2, you might be able to replace the GC interface with a "debug" interface that just forwards calls to the normal GC. This is a capability druntime inherited from the Tango runtime - the GC is separated from the rest of the standard library and can actually be replaced at link-time. I don't know if D2 links all three parts of druntime into a single library or not, though.Someone should make such a GC shell. You could add a BanAlloc(bool) option that would turn on an assert on any allocation. This could be set and cleared around the RT parts of the code.
Feb 24 2009
Yes, this would be a great idea, especially for RT production software. wade Denis Koroskin Wrote:On Tue, 24 Feb 2009 20:40:13 +0300, BCS <ao pathlink.com> wrote:Reply to Jarrett,Good idea!Hm, actually.. If you *are* using D2, you might be able to replace the GC interface with a "debug" interface that just forwards calls to the normal GC. This is a capability druntime inherited from the Tango runtime - the GC is separated from the rest of the standard library and can actually be replaced at link-time. I don't know if D2 links all three parts of druntime into a single library or not, though.Someone should make such a GC shell. You could add a BanAlloc(bool) option that would turn on an assert on any allocation. This could be set and cleared around the RT parts of the code.
Feb 24 2009
Reply to wade,Yes, this would be a great idea, especially for RT production software. wade Denis Koroskin Wrote:For production software it would get tricky. Are you better of doing the alloc or just failing?
Feb 24 2009
Thanks, That's helpful. I'm using D 1.0. I've eliminated all array concats, dups, etc. but there's still a significant amount of memory being allocated that I can't seem to detect. Perhaps, I can recompile an instrumented version of phobos... wade Jarrett Billingsley Wrote:On Tue, Feb 24, 2009 at 12:00 PM, wade Shen <swadenator gmail.com> wrote:I'm writing some performance sensitive code (real time processing) for which I've tried to minimize the number of memory allocations by using preallocated objects pools. Unfortunately, during the course of running, it seems that lots of memory is still getting allocated even though all explicit "new" and array slicing operations have been moved out of the main processing loops. As a result the program is quite slow when garbage collection is enabled (but very fast otherwise).Array slicing does not cause the GC to run. It is essentially free, which is a wonderful thing.Is there a way to track down where memory is being allocated if I'm using phobos? Any recommendations would be appreciated.This is something I have *always* wanted. Unfortunately I don't think it's possible to add such instrumentation without modifying and recompiling Phobos. Even if you're using D2, which uses druntime, there's no such thing. Hm, actually.. If you *are* using D2, you might be able to replace the GC interface with a "debug" interface that just forwards calls to the normal GC. This is a capability druntime inherited from the Tango runtime - the GC is separated from the rest of the standard library and can actually be replaced at link-time. I don't know if D2 links all three parts of druntime into a single library or not, though. Here are some other things that could be causing allocation: - Array appending (~=) can cause it; array concatenation (~) is guaranteed to cause it. - Array .dup. - Adding items to associative arrays. - In D2, nested functions/anonymous delegates can allocate memory secretly, unless you're careful and only pass them to "scope" delegate parameters.
Feb 24 2009
Jarrett Billingsley wrote:On Tue, Feb 24, 2009 at 12:00 PM, wade Shen <swadenator gmail.com> wrote:which I've tried to minimize the number of memory allocations by using preallocated objects pools. Â Unfortunately, during the course of running, it seems that lots of memory is still getting allocated even though all explicit "new" and array slicing operations have been moved out of the main processing loops. Â As a result the program is quite slow when garbage collection is enabled (but very fast otherwise).I'm writing some performance sensitive code (real time processing) forArray slicing does not cause the GC to run. It is essentially free, which is a wonderful thing.phobos? Any recommendations would be appreciated.Is there a way to track down where memory is being allocated if I'm usingThis is something I have *always* wanted. Unfortunately I don't think it's possible to add such instrumentation without modifying and recompiling Phobos. Even if you're using D2, which uses druntime, there's no such thing.Might it be possible to use tangobos for this purpose and just add asserts in the GC code? Last time I looked it was pretty straightforward to recompile Tango.
Feb 24 2009
Thanks again for all the help. I found what the problem was and it wasn't obvious (at least to me): float[uint] arr; foreach (uint k; arr.keys) { ... } Changing this to: foreach (uint k, float v; arr) { ... } fixes the leak. I guess the keys array is constructed on the fly? wade Lutger Wrote:Jarrett Billingsley wrote:On Tue, Feb 24, 2009 at 12:00 PM, wade Shen <swadenator gmail.com> wrote:which I've tried to minimize the number of memory allocations by using preallocated objects pools. Â Unfortunately, during the course of running, it seems that lots of memory is still getting allocated even though all explicit "new" and array slicing operations have been moved out of the main processing loops. Â As a result the program is quite slow when garbage collection is enabled (but very fast otherwise).I'm writing some performance sensitive code (real time processing) forArray slicing does not cause the GC to run. It is essentially free, which is a wonderful thing.phobos? Any recommendations would be appreciated.Is there a way to track down where memory is being allocated if I'm usingThis is something I have *always* wanted. Unfortunately I don't think it's possible to add such instrumentation without modifying and recompiling Phobos. Even if you're using D2, which uses druntime, there's no such thing.Might it be possible to use tangobos for this purpose and just add asserts in the GC code? Last time I looked it was pretty straightforward to recompile Tango.
Feb 24 2009
wade wrote:Thanks again for all the help. I found what the problem was and it wasn't obvious (at least to me): float[uint] arr; foreach (uint k; arr.keys) { ... } Changing this to: foreach (uint k, float v; arr) { .... } fixes the leak. I guess the keys array is constructed on the fly? wadeYup. It's a pity that we don't have, oh I don't know, some sort of efficient iterable interface that doesn't cause a heap allocation that the runtime could use instead *cough*hint*cough*andrei*cough*ranges*cough*. -- Daniel
Feb 24 2009
On Tue, Feb 24, 2009 at 8:23 PM, Daniel Keep <daniel.keep.lists gmail.com> wrote:Yup. It's a pity that we don't have, oh I don't know, some sort of efficient iterable interface that doesn't cause a heap allocation that the runtime could use instead *cough*hint*cough*andrei*cough*ranges*cough*.You can use "foreach(k; aa)" and "foreach(_, v; aa)". The thing is they're not always substitutes for .keys and .values. For example, if you want to modify the AA during the foreach loop, you have to use something like "foreach(k; aa.keys)" since you need a "snapshot" of the keys as they were before you started modifying it.
Feb 24 2009
Jarrett Billingsley wrote:On Tue, Feb 24, 2009 at 8:23 PM, Daniel Keep <daniel.keep.lists gmail.com> wrote:True; although I'm one of those people who stays up at night, plotting the gruesome demise of invisible allocations, so I tend to do manually create and destroy the storage for the keys. In a perfect world, we'd have extension methods, and then we could just do this: RangeType!(T)[] toArray(T)(ref T this) if isRange!(T) { ... } foreach( k ; aa.keys.toArray ) ... My own policy is that if you have to choose between two designs, one where you always allocate and the other where you can optionally allocate, go for the second. -- DanielYup. It's a pity that we don't have, oh I don't know, some sort of efficient iterable interface that doesn't cause a heap allocation that the runtime could use instead *cough*hint*cough*andrei*cough*ranges*cough*.You can use "foreach(k; aa)" and "foreach(_, v; aa)". The thing is they're not always substitutes for .keys and .values. For example, if you want to modify the AA during the foreach loop, you have to use something like "foreach(k; aa.keys)" since you need a "snapshot" of the keys as they were before you started modifying it.
Feb 24 2009
On Tue, Feb 24, 2009 at 8:04 PM, wade <swadenator gmail.com> wrote:fixes the leak. =A0I guess the keys array is constructed on the fly?Oh, yes X| .keys and .values of AAs are constructed whenever you use them.
Feb 24 2009
Jarrett Billingsley wrote:On Tue, Feb 24, 2009 at 12:00 PM, wade Shen <swadenator gmail.com> wrote:This has been on my "to do" list forever. One of these days I'll actually get to it :-)Is there a way to track down where memory is being allocated if I'm using phobos? Any recommendations would be appreciated.This is something I have *always* wanted. Unfortunately I don't think it's possible to add such instrumentation without modifying and recompiling Phobos. Even if you're using D2, which uses druntime, there's no such thing.Hm, actually.. If you *are* using D2, you might be able to replace the GC interface with a "debug" interface that just forwards calls to the normal GC. This is a capability druntime inherited from the Tango runtime - the GC is separated from the rest of the standard library and can actually be replaced at link-time. I don't know if D2 links all three parts of druntime into a single library or not, though.It does. Partially because the three-library approach seems to have problems on Linux (there are link errors even though everything needed is actually present). But the GC is still easily replaceable. In fact, D2 provides an undocumented way to redirect GC calls, but I don't think it will currently work for this form of interception--you'd end up with an endless loop. Sean
Feb 25 2009