高分,内存的实时回收。

a854468521 2010-01-17 09:24:27
在程序中使用了一个不断的添加子窗体和不断关闭子窗体,主程序的内存消耗一直在增加,在主程序中
调用Collect,执行后也未见任何效果。
即使在任务管理器中看到该进程的内存消耗下降但总的内存消耗反而是上升的.
如果不能强制的内存回收,该程序消耗的内存将导致资源耗尽,系统崩溃。
Private Sub Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Collect = New PublicData.Collect

End Sub
'添加子窗体
'子窗体内只有一个AxCell1控件(用友的Cell1表格控件).

Private Sub AddF_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AddF.Click
Sheet = New Sheet.Sheet
sheet.MdiParent = Me
sheet.Show()
End Sub
'关闭子窗体
Private Sub CloseF_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CloseF.Click
Sheet = Me.ActiveMdiChild
Sheet.Dispose()
End Sub


'强制清理内存
Public Class Collect
Dim Thread As Threading.Thread
Public Sub New()
' 开启清理线程
Thread = New Threading.Thread(AddressOf Clear)
Thread.Priority = Threading.ThreadPriority.Highest
Thread.Start()
End Sub
Private Sub Clear()
'进行垃圾清理。
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
Threading.Thread.Sleep(1000)
End Sub
Public Sub Close()
'关闭线程
Thread.Join(1)
MyBase.Finalize()
End Sub
End Class



...全文
229 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
解释多余的 2010-01-20
  • 打赏
  • 举报
回复
up
足球中国 2010-01-18
  • 打赏
  • 举报
回复
不用管。用到一定时候,他自然会回收。。
你不要拭和动去处理这个问题。


垃圾回收要挂起所有的线程。才能进行回收。

你不用理会。让他自己弄是的。
如果你用了非拖管代码。要自己null一下。释放一下内存。
古今多少事 2010-01-18
  • 打赏
  • 举报
回复
UP!
oo渣渣oo 2010-01-18
  • 打赏
  • 举报
回复
收藏等结果
fut20090715 2010-01-18
  • 打赏
  • 举报
回复
应该是“用友的Cell1表格控件”占用了大量的内存资源
如果可以用一个这种窗体搞定的话
就尽量重复利用这个窗体


再有就是可能引用了大对象资源
这种资源是目前framework无法回收的
可以参见http://www.cnblogs.com/futao/archive/2009/12/23/1630461.html
cuike519 2010-01-18
  • 打赏
  • 举报
回复
楼主有兴趣看看下面这个连接的内容,我对.NET的内存做了一个简单的分析:
http://blog.csdn.net/cuike519/archive/2009/12/23/5063333.aspx

你要找出哪些内存它应该是垃圾但是在你调用了垃圾回收之后它没有被回收,也就是说系统认为它不是垃圾,找出这些内存再做程序层面的分析,程序哪里分配了这些内存,这些内存分配的是否合理?

另外,你需要知道托管和非托管内存的增长情况,找到你现在是非托管内存泄漏还是托管内存泄露,这个用性能计数器能很容易的看出来,另外通过你的程序也能识别出来?

IDispose是用来释放非托管资源的一种规范,非托管资源必须显式的释放,垃圾回收不会帮你释放的,所以涉及到非托管资源的时候必须实现这个接口,该接口的调用是由框架完成的。
wuhuwy 2010-01-18
  • 打赏
  • 举报
回复
使用托管进行垃圾回收吧
水猿兵团五哥 2010-01-18
  • 打赏
  • 举报
回复
dispose
lihaidomain 2010-01-17
  • 打赏
  • 举报
回复
既然是重复的窗口,干嘛不用隐藏呢??
xiaoyaocao 2010-01-17
  • 打赏
  • 举报
回复
线程执行体无循环?
chenglidexiaoxue 2010-01-17
  • 打赏
  • 举报
回复
子窗体内是否有非托管资源啊,那需要手动销毁,
a854468521 2010-01-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 vrhero 的回复:]
过于频繁调用GC.Collect()反而会引起GC效率下降,资源无法及时释放...不可干预托管资源回收...

总得来说是你的逻辑有问题,“不断的添加子窗体和不断关闭子窗体”即使是C++也不合逻辑...
[/Quote]

我是使用子窗体来显示表格AxCell1控件(用友的Cell1表格控件),实现类似EXCEL多工作簿的功能,所有需要实时的添加或关闭子窗体。
我测试过了,使用原版的AxCell1控件(用友的Cell1表格控件)没问题(内存可以释放),可能是XXX的技术还不行。
vrhero 2010-01-17
  • 打赏
  • 举报
回复
过于频繁调用GC.Collect()反而会引起GC效率下降,资源无法及时释放...不可干预托管资源回收...

总得来说是你的逻辑有问题,“不断的添加子窗体和不断关闭子窗体”即使是C++也不合逻辑...
seesea125 2010-01-17
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 a854468521 的回复:]
引用 7 楼 seesea125 的回复:
'进行垃圾清理。
        GC.Collect()
        GC.WaitForPendingFinalizers()
        GC.Collect()

看你代码,都是使用的托管资源,托管资源本身已经很安全了,占用内存,可能和你写程序写的不合理有关,操作GC,不是解决办法,而且操作GC,会带来其他的不安全问题

我写的程序没什么问题,只是加载了一些子窗体用于显示表格(有点像EXCEL的多工作簿)。
可能是该AxCell1控件(用友的Cell1表格控件)的问题,该控件是XXX的!
使用 Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long,
还是不能释放该控件占有的内存.
[/Quote]

如果是这样的话,那就是引用了非托管资源啊,非托管资源,通过GC回收不了的。

GC回收的对象是托管堆上的资源,也就是由CLR管理的内存资源。所以诸如数据库连接之类的资源都不是GC能够直接释放的。是对象本身释放的。对象通过实现IDisposable接口或者定义Finalize方法来告诉CLR在适当的时候(try/catch/finally语句中或者是由GC引起的Finalize方法)调用对象的Dispose或者Finalize函数,来释放这些资源。

所以,关于非托管堆上的资源,有以下论述:
1. 持有这些资源的对象负责清理他们,所以在问答ADO.net中哪些资源应该被释放的时候,应该查阅ADO.net的相关文档,来回答这些问题。
2. 清理对象的时机取决于调用者
a) 如果对象实现了IDisposable接口,那么try/catch/finally或者是using语句中,该对象的Dispose()方法会被调用,从而清理相关资源。
b) 如果对象实现了Finalize方法,那么当对象没有引用的时候,GC.Collect会触发Finalizer线程调用该对象的Finalize方法。但是要注意此时并不保证GC.Collect结束之后,该对象的Finaliz方法一定会被调用。原因我在这篇博客中交代了http://blog.csdn.net/mountaintaiII/archive/2009/04/13/4071271.aspx
a854468521 2010-01-17
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 seesea125 的回复:]
'进行垃圾清理。
        GC.Collect()
        GC.WaitForPendingFinalizers()
        GC.Collect()

看你代码,都是使用的托管资源,托管资源本身已经很安全了,占用内存,可能和你写程序写的不合理有关,操作GC,不是解决办法,而且操作GC,会带来其他的不安全问题
[/Quote]
我写的程序没什么问题,只是加载了一些子窗体用于显示表格(有点像EXCEL的多工作簿)。
可能是该AxCell1控件(用友的Cell1表格控件)的问题,该控件是XXX的!
使用 Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long,
还是不能释放该控件占有的内存.
seesea125 2010-01-17
  • 打赏
  • 举报
回复
'进行垃圾清理。
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()

看你代码,都是使用的托管资源,托管资源本身已经很安全了,占用内存,可能和你写程序写的不合理有关,操作GC,不是解决办法,而且操作GC,会带来其他的不安全问题
seesea125 2010-01-17
  • 打赏
  • 举报
回复
托管代码不用考虑资源回收的问题
wuyq11 2010-01-17
  • 打赏
  • 举报
回复
托管代码的开发,不用操心资源回收。.NETFramework会在认为合适的时候完成。
非托管代码的开发,必须自己指定资源回收的方式和时机。
继承IDispose接口
josephSC 2010-01-17
  • 打赏
  • 举报
回复
up
wild_wolf99 2010-01-17
  • 打赏
  • 举报
回复
帮你up!

16,555

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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