diff options
author | Dr Scofield | 2009-06-03 12:39:44 +0000 |
---|---|---|
committer | Dr Scofield | 2009-06-03 12:39:44 +0000 |
commit | 074b66ddcf5297ded473e8b275f77303c13fa5f1 (patch) | |
tree | 221891cc32a953bdd91edb141fa2b5df63d2d89c /OpenSim | |
parent | From: Alan Webb <alan_webb@us.ibm.com> (diff) | |
download | opensim-SC-074b66ddcf5297ded473e8b275f77303c13fa5f1.zip opensim-SC-074b66ddcf5297ded473e8b275f77303c13fa5f1.tar.gz opensim-SC-074b66ddcf5297ded473e8b275f77303c13fa5f1.tar.bz2 opensim-SC-074b66ddcf5297ded473e8b275f77303c13fa5f1.tar.xz |
From: Chris Yeoh <yeohc@au1.ibm.com>
- fixes wild swings in memory usage related to usage of GetDrawStringSize()
We've been seeing wild swings in memory usage and a large chunk of
memory leak. From analysing this it's pretty clear that the mono
garbage collector is rather buggy! When exercised heavily it looks
like it frees more than its meant to resulting in crashes.
GetDrawStringSize() measures the size in pixels of text. To do this
memory for an image is allocated and used to call the GDI text
measure functions. Although no reference to the temporary memory
for the measuring is kept, it takes quite a while for the mono
garbage collector to clean up - so if lots calls to
GetDrawStringSize() are made at once there can be a spike in memory
usage. If the garbage collector is not fast enough then the GDI
layer runs out of memory. It also looks like the garbage collector
is not always reclaiming all of the memory.
I've attached an OpenSim patch which works around the garbage collector
issues. Instead of dynamically allocating memory for measuring
text sizes, it serialises (on a per region basis) access to a single
block of memory. The effect of this is to be nicer to the garbage
collector as it has a lot less work to do, at the cost of some
theoretical loss in performance (nothing noticeable with our tests
which hit it pretty hard).
OpenSim still does leak memory slowly, but it is a lot more stable
with this patch. I suspect that either the garbage collector misses
bits of freed memory or the GDI/cairo layer leaks a bit each time a
texture is created. Thats going to be a lot harder to hunt down, but
for reference if someone has OpenSim running on Windows it would be
interesting to see if it has the same problem as it would tell us if
its a mono/GDI problem or an OpenSim problem.
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 90c48d0..2640f08 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs | |||
@@ -50,7 +50,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
50 | private string m_name = "VectorRenderModule"; | 50 | private string m_name = "VectorRenderModule"; |
51 | private Scene m_scene; | 51 | private Scene m_scene; |
52 | private IDynamicTextureManager m_textureManager; | 52 | private IDynamicTextureManager m_textureManager; |
53 | 53 | private Graphics m_graph; | |
54 | |||
54 | public VectorRenderModule() | 55 | public VectorRenderModule() |
55 | { | 56 | { |
56 | } | 57 | } |
@@ -96,14 +97,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
96 | public void GetDrawStringSize(string text, string fontName, int fontSize, | 97 | public void GetDrawStringSize(string text, string fontName, int fontSize, |
97 | out double xSize, out double ySize) | 98 | out double xSize, out double ySize) |
98 | { | 99 | { |
99 | Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb); | ||
100 | Graphics graph = Graphics.FromImage(bitmap); | ||
101 | |||
102 | Font myFont = new Font(fontName, fontSize); | 100 | Font myFont = new Font(fontName, fontSize); |
103 | SizeF stringSize = new SizeF(); | 101 | SizeF stringSize = new SizeF(); |
104 | stringSize = graph.MeasureString(text, myFont); | 102 | lock (m_graph) { |
105 | xSize = stringSize.Width; | 103 | stringSize = m_graph.MeasureString(text, myFont); |
106 | ySize = stringSize.Height; | 104 | xSize = stringSize.Width; |
105 | ySize = stringSize.Height; | ||
106 | } | ||
107 | } | 107 | } |
108 | 108 | ||
109 | 109 | ||
@@ -117,6 +117,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
117 | { | 117 | { |
118 | m_scene = scene; | 118 | m_scene = scene; |
119 | } | 119 | } |
120 | |||
121 | if (m_graph == null) | ||
122 | { | ||
123 | Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb); | ||
124 | m_graph = Graphics.FromImage(bitmap); | ||
125 | } | ||
120 | } | 126 | } |
121 | 127 | ||
122 | public void PostInitialise() | 128 | public void PostInitialise() |