Arcgis Engine开发在Scenecontrol上添加text动态更新时内存不断增长

baojay1989 2015-03-01 05:44:14
各位大神:
小弟在用vs2012下C#写基于arcgis 的一个三维应用程序。
需求很简单,需要讲一个人的位置和运行时间计算出来,在scenecontrol上动态显示。
于是我创建了一个graphicslayer,然后定义了一个graphicscontainer = graphicslayer as Igraphicscontainer
于是又创建了一个text3delement,定义了这个text的各种属性,当然也包括一些symbol等等,
最后把这个text3delement给graphicscontainer.addelement(text3delement);
this.axscenecontrol.scene.addlayer(graphicslayer );
然后刷新该图层;
这样添加了一个三维文字,因为秒表要定时刷新,因此我采用了两个办法,一个是定时器,一个是开线程后thread.sleep(1000);
在timer或者thread的响应函数中,分别使用过委托/消息 的办法去刷新text3delement,
当然重要的是,我刷新的办法:将text3delement定义成全局,然后在刷新的这里重新将text3delement的位置和text属性赋值,然后text3delement.update();然后刷新
这时,我的应用程序内存暴涨,好像完全没有释放的意思,但是我想,我在刷新这块应该只是update了一些啊,没有创建什么新的东西啊
后来我测试了一下,如果我改变text3delement的内容少一些,内存增长就少一些,如果不变 ,内存就不涨,即使执行text3delement.update();
那么问题来了,是我不会用这个update呢,还是我应该怎么去主动释放一下内存呢?
...全文
429 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
baojay1989 2015-03-07
  • 打赏
  • 举报
回复
引用 14 楼 u012488787 的回复:
你的内存常占用到80%左右,是么?? arcgis本来就需要很多内存,就算你不做什么处理,也是。 而且三维的占用内存就更多了。 你可以试试写二维的文字,看看占用情况,再做分析。 ArcGIS Engine开发中,一般cursor相关我都释放; using(ComReleaser pComReleaser=new ComReleaser()) { ICursor queryCursor = queryTableSort.Rows; pComReleaser.ManageLifetime(queryCursor); } 我现在采用这种释放资源的方式,是engine中自己的资源释放方式。 但不是所有的都要释放。 你如果用.net的释放方式: System.Runtime.InteropServices.Marshal.ReleaseComObject(queryCursor); System.GC.Collect(); 而且这种释放,尽量不要放在循环中。
明白了。我的内存到了92%-93%,程序就变得很卡,然后好像也不会再特别往上涨了。给esri发邮件问这个问题,美国那边说update就是会导致内存上涨,看来只有换个内存大的电脑了。
gis_99 2015-03-06
  • 打赏
  • 举报
回复
你的内存常占用到80%左右,是么?? arcgis本来就需要很多内存,就算你不做什么处理,也是。 而且三维的占用内存就更多了。 你可以试试写二维的文字,看看占用情况,再做分析。 ArcGIS Engine开发中,一般cursor相关我都释放; using(ComReleaser pComReleaser=new ComReleaser()) { ICursor queryCursor = queryTableSort.Rows; pComReleaser.ManageLifetime(queryCursor); } 我现在采用这种释放资源的方式,是engine中自己的资源释放方式。 但不是所有的都要释放。 你如果用.net的释放方式: System.Runtime.InteropServices.Marshal.ReleaseComObject(queryCursor); System.GC.Collect(); 而且这种释放,尽量不要放在循环中。
gis_99 2015-03-05
  • 打赏
  • 举报
回复
我感觉你的内存偏小,我做arcgis engine开发,去年是4G内存,做数据生产或数据质量检查的时候,或者加载mxd中地形图多点,就很慢。 后来内存升到16G,装64位win7,再做上面同样的操作,速度快很多。 个人感觉arcgis做图像、数据处理的时候就消耗内存多。
baojay1989 2015-03-05
  • 打赏
  • 举报
回复
引用 12 楼 u012488787 的回复:
我感觉你的内存偏小,我做arcgis engine开发,去年是4G内存,做数据生产或数据质量检查的时候,或者加载mxd中地形图多点,就很慢。 后来内存升到16G,装64位win7,再做上面同样的操作,速度快很多。 个人感觉arcgis做图像、数据处理的时候就消耗内存多。
恩,看来我的确需要换个大点的试试,但是我的工程占用的物理内存急剧增长,为什么C#没有主动给我释放内存呢?是因为C#的内存管理机制认为还没必要释放内存,还是因为Arcgis engine创建的对象被scenecontrol引用所以没办法释放呢》?
於黾 2015-03-04
  • 打赏
  • 举报
回复
接上文, GC.Collect()就是通知清洁工可以进行清理了 它不代表清洁工就马上会来,但是总是比不知道他什么时候有心情了来一趟要快一些就是了 清洁工什么时候开始清理呢?定时清理;空间不足时清理 那么很显然的,定时的时间和空间不足的剩余量,这些肯定会和你空间总大小是有关的 如果你内存足够大,就不需要清理的太频繁,清理太频繁反而吃CPU,降低效率
於黾 2015-03-04
  • 打赏
  • 举报
回复
值类型的对象不存在"释放"的问题 只有引用类型的对象需要释放 而引用类型又分为托管的和非托管的,托管的不用你手动执行释放,没有对象去引用它了,GC就会负责回收它 而非托管资源需要你主动告知哪些是可以释放的(使用Dispose) 其实GC就好比清洁工,托管资源就类似苹果核,瓜子皮,烟头这些东西,一看就知道是不是需要丢掉 而非托管资源就是写了字的纸,你不丢进垃圾桶,没人敢随便扔掉的
於黾 2015-03-04
  • 打赏
  • 举报
回复
没看到任何一句Dispose(),却看到了GC.Collect(); 这就好像你通知清洁工倒垃圾,但是垃圾桶里其实什么都没放进去,东西都拿在你自己手上,那么清洁工不可能从你手上抢你正看的文件丢掉,你通知她来打扰你,反而耽误了你的正常工作 不要在循环里执行GC.Collect(),这没啥意义
baojay1989 2015-03-04
  • 打赏
  • 举报
回复
引用 10 楼 Z65443344 的回复:
接上文, GC.Collect()就是通知清洁工可以进行清理了 它不代表清洁工就马上会来,但是总是比不知道他什么时候有心情了来一趟要快一些就是了 清洁工什么时候开始清理呢?定时清理;空间不足时清理 那么很显然的,定时的时间和空间不足的剩余量,这些肯定会和你空间总大小是有关的 如果你内存足够大,就不需要清理的太频繁,清理太频繁反而吃CPU,降低效率
但是现在的情况是,就这段代码,我的电脑4g内存2.18g可用,运行起来以后,一直占用物理内存到1.3g左右的时候,程序界面就死了。就相当于是直接未响应了。根本没有内存释放这个现象,这样不对吧?可是我也实在看不出来有什么dispose 的,我都定义的全局的。我把这段代码发给esri公司了,我感觉是这个text3delement.update();函数造成不自动释放的。
baojay1989 2015-03-03
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
[quote=引用 2 楼 baojay1989 的回复:] [quote=引用 1 楼 u012488787 的回复:] 根据你说的,没发现需要释放的资源。
涨到了1G多还在增长,界面已经卡的不能工作了。[/quote] 你的物理内存都用光了吗?如果没有用光,那么你得“卡”就不是内存问题(而是你程序UI线程或者整个CPU占用问题),相反这个时候就不应该花时间去释放内存。[/quote]
引用 4 楼 caozhy 的回复:
线程操作有没有用invoke委托?
比如这段代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.IO.Ports; using System.Runtime.InteropServices; using System.Threading; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.SystemUI; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.DataSourcesFile; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Analyst3D; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.GlobeCore; namespace WindowsFormsApplication3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); InitTimer(); text3DElement = new Text3DElementClass(); graphicsLayer = new GraphicsLayer3DClass(); Init3DText(); } System.Windows.Forms.Timer Updatetimer; IGraphicsLayer graphicsLayer;//将graphics图层定义为全局,就这么一个图层 IText3DElement text3DElement;//同上,将这个3delement也定义为全局 IGraphicsContainer3D graphicsContainer3D;//这个也是 int i = 0; public void InitTimer() { Updatetimer = new System.Windows.Forms.Timer(); Updatetimer.Interval = 100;//定时器时间设为100ms,直观看到内存的增长。 Updatetimer.Tick += new EventHandler(Updatetimer_Tick); } public void Init3DText() { graphicsContainer3D = graphicsLayer as IGraphicsContainer3D; text3DElement.FontName = "name"; text3DElement.Text = "开始"; text3DElement.AnchorPoint.X = 0; text3DElement.AnchorPoint.Y = 0; text3DElement.AnchorPoint.Z = 0; text3DElement.Depth = 0.5; text3DElement.Height = 2; text3DElement.Height = 2; text3DElement.BoldFont = true; text3DElement.RotationAngle = 360; ISimpleFillSymbol simpleFillSymbol = new SimpleFillSymbol(); IRgbColor color = new RgbColorClass(); color.Red = 255; simpleFillSymbol.Color = color; IFillShapeElement fillShapeElement = text3DElement as IFillShapeElement; fillShapeElement.Symbol = simpleFillSymbol as IFillSymbol; graphicsContainer3D.AddElement(text3DElement as IElement); text3DElement.Update();//这里如果不添加update就显示不出来了。。。 this.axSceneControl1.Scene.AddLayer(graphicsLayer as ILayer); this.axSceneControl1.SceneGraph.Invalidate(graphicsLayer, true, false); this.axSceneControl1.SceneGraph.RefreshViewers(); } int num = 0; public void Updatetimer_Tick(object sender, EventArgs e) { i++; string text = text3DElement.Text; text = "是" + i;//还有这儿,如果我什么都不改,光update,当然是内存不变,就是说把这句删掉,不变 text3DElement.Text = text;//我就改了一下text涨这么厉害 text3DElement.Update();//内存飙升啊,就这句话 num = graphicsContainer3D.ElementCount;//这里看了下,graphicsContainer3D的确一直只有一个element存在 this.axSceneControl1.SceneGraph.Invalidate(graphicsLayer, true, false); this.axSceneControl1.SceneGraph.RefreshViewers(); GC.Collect();//这儿除了这句话,我也不知道有啥可释放的了, } private void button_Referesh_Click(object sender, EventArgs e) { Updatetimer.Start();//button,开启100ms定时器刷新 } private void button1_Click(object sender, EventArgs e) { text3DElement.Update();//单纯想看看这句话到底怎么回事,狂点五百多下button以后发现,涨一会儿,停一会儿,但是比修改text3delement肯定好多了 } private void button2_Click(object sender, EventArgs e) { while(true)//死循环,哗哗的涨啊 { i++; string text = text3DElement.Text; text = "是" + i; text3DElement.Text = text; text3DElement.Update(); num = graphicsContainer3D.ElementCount; this.axSceneControl1.SceneGraph.Invalidate(graphicsLayer, true, false); this.axSceneControl1.SceneGraph.RefreshViewers(); GC.Collect(); } } } } 这是我写的测试程序,里面涉及到arcgis一些控件。
baojay1989 2015-03-03
  • 打赏
  • 举报
回复
引用 4 楼 caozhy 的回复:
线程操作有没有用invoke委托?
当然有用,之前是用system.timers.timer用的委托,后来试过system.windows.form.timer,这定时器是可以直接操作UI的
baojay1989 2015-03-03
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
[quote=引用 2 楼 baojay1989 的回复:] [quote=引用 1 楼 u012488787 的回复:] 根据你说的,没发现需要释放的资源。
涨到了1G多还在增长,界面已经卡的不能工作了。[/quote] 你的物理内存都用光了吗?如果没有用光,那么你得“卡”就不是内存问题(而是你程序UI线程或者整个CPU占用问题),相反这个时候就不应该花时间去释放内存。[/quote] 没有用完,我2g的,用到1g多的时候,我UI还是可以操作,但是当操作界面的时候(我理解每次操作都相当于让界面刷新),都会出现“卡”的情况,就是当我滑动三维控件,从原始位置直接到了最终位置。我理解这个是卡。程序还在增长内存,这是为什么呢,我的CPU才不到10%,UI上面一直执行的都是刷新线程。
threenewbee 2015-03-02
  • 打赏
  • 举报
回复
线程操作有没有用invoke委托?
  • 打赏
  • 举报
回复
引用 2 楼 baojay1989 的回复:
[quote=引用 1 楼 u012488787 的回复:] 根据你说的,没发现需要释放的资源。
涨到了1G多还在增长,界面已经卡的不能工作了。[/quote] 你的物理内存都用光了吗?如果没有用光,那么你得“卡”就不是内存问题(而是你程序UI线程或者整个CPU占用问题),相反这个时候就不应该花时间去释放内存。
gis_99 2015-03-02
  • 打赏
  • 举报
回复
根据你说的,没发现需要释放的资源。
baojay1989 2015-03-02
  • 打赏
  • 举报
回复
引用 1 楼 u012488787 的回复:
根据你说的,没发现需要释放的资源。
涨到了1G多还在增长,界面已经卡的不能工作了。

110,546

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧