Auto-scrolling text box uses more memory than expected

前端 未结 2 2088
挽巷
挽巷 2020-12-13 15:48

I have an application that logs messages to the screen using a TextBox. The update function uses some Win32 functions to ensure that the box automatically scrolls to the end

相关标签:
2条回答
  • 2020-12-13 16:34

    Tracking the amount of memory used by an application, especially a garbage collected language, is a tricky undertaking. People often used the overall memory count for an application to determine the objects still in use (for instance via task manager). This is questionably effective for native application but will give very misleading results for managed applications.

    In order to correctly determine the amount of memory used by your CLR objects, you need to use a tool that is specifically geared to measuring that. For instance, I find the best way is to use a combination of WinDbg and sos.dll to measure the current rooted objects. This will both tell you the size of your managed objects and point out what objects are actually taking up the extra memory.

    Here's a nice article on the subject

    • http://blogs.msdn.com/delay/archive/2009/03/11/where-s-your-leak-at-using-windbg-sos-and-gcroot-to-diagnose-a-net-memory-leak.aspx
    0 讨论(0)
  • 2020-12-13 16:37

    How are you determining the memory usage? You'd have to watch the CLR memory usage for your application, not the memory used by the system for the whole application (you can use Perfmon for that). Perhaps you are already using the correct method of monitoring.

    It seems to me that you are using StringBuilder internally. If so, that would explain the doubling of the memory, because that's the way StringBuilder works internally.

    The GC.Collect() may not do anything if the references to your objects are still in scope, or if any of your code uses static variables.


    EDIT:
    I'll leave the above, because it may still be true, but I looked up AppendText's internals. It does not append (i.e., to a StringBuilder), instead, it sets the SelectedText property, which does not set a string but sends a Win32 message (string is cached on retrieval).

    Because strings are immutable, this means, for every string, there will be three copies: one in the calling application, one in the "cache" of the base Control and one in the actual Win32 textbox control. Each character is two bytes wide. This means that any 1MB of text, will consume 6MB of memory (I know, this is a bit simplistic, but that's basically what seems happening).

    EDIT 2: not sure if it'll make any change, but you can consider calling SendMessage yourself. But it sure starts to look like you'll need your own scrolling algorithm and your own owner-drawn textbox to get the memory down.

    0 讨论(0)
提交回复
热议问题