关于vb.net调用dll时的内存问题

rabiboy 2020-03-28 05:18:35
各位大神,小弟使用MATLAB的com组件方式将.m的函数打包生成了dll,然后在vb.net中调用。程序如下,在界面载入时我进行了初始化(由于初始化速度慢,所以在载入窗口时选择了初始化,而没有在后续调用之前初始化),然后当点击“按钮1”和“按钮2”是分别可以使用不同的参数调用已经初始化的函数计算。但是我在调试的过程中发现,当使用按钮1和按钮2进行了多次计算后,会弹出提示“尝试读写受保护的内存”,这个时候就没法继续使用了,只能关闭软件并重新再打开。请教一下各位大神这是由于多次使用calculation_function1函数导致的么?我应该怎么处理能避免出现这个问题?在此先行谢过。
Public Class Form1
Public calculation_function1 As add_com.jisuan‘引用dll
Dim c As Double
'界面载入
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
calculation_function1 = New add_com.jisuan '载入时初始化
End Sub
'按钮1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
calculation_function1.add(1, c, 参数1, 参数2)
End Sub
'按钮2
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
calculation_function1.add(1, c, 参数3, 参数4)
End Sub
End Class
...全文
687 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
rabiboy 2020-04-16
  • 打赏
  • 举报
回复
引用 10 楼 raynors 的回复:
[quote=引用 9 楼 rabiboy的回复:][quote=引用 8 楼 raynors 的回复:]
你本身的代码那么简单怎么可能有问题,第一反应应该就是DLL出错了.

从字面上分析,就是多次调用产生的多个线程 访问共享内存 产生的冲突.

简单点说.

你两个按钮同时按,肯定会出问题,因为第一次运算还没计算出结果, 第二次运算呼叫过去了,必然会产生某些冲突,除非你函数设计上是多线程且不互相依赖的.

应该要设置一个返回值,表示计算已完成,才能进行下一次呼叫.

感谢回复,您说的这个是指我应该在单次调用完成后先返回一个告知完成的变量再进行下次点击操作么?我实际上在每次调用完在matlab里面写了个弹出窗口通知计算完成,然后我每次点击按钮的操作是在获得计算完成的通知后才再次点击的。[/quote]
监控一下内存使用情况。

如果点一次计算增长,结束后不释放,也会存在内存泄露问题[/quote]
麻烦大神能不能给看一下这个情况,我又使用了一个简单的模型来测内存。使用matlab的函数(一个很简单的求和函数)生成了com组件,然后在vb.net中进行调用。在进行调用时,发现如果使用下面的方式内存会一直增加。ReleaseComObject返回的值n是0,表示应该已经释放完了,但是内存一直没有下降。
calculation_function1 = New add_com.jisuan '载入时初始化
For i = 1 To 1000
calculation_function1.add(1, c, i, 2)
TextBox1.Text = c
Next
n = Marshal.ReleaseComObject(calculation_function1)
但是我使用下面的方法时,内存一直很稳定。我的问题是同样是调用多次calculation_function1,初始化和释放的位置不同(比如我这两个例子)为什么会导致内存一个释放完成,一个释放未完成呢? 上面的程序,在循环外面进行初始化是我希望的,因为每次初始化com组件时速度比较慢,所以同样是进行完整的一次循环,计算速度上面明显要快。有什么办法修改代码即保证计算速度,同时内存又可以正确释放呢?先行谢过。
For i = 1 To 1000
calculation_function1 = New add_com.jisuan '载入时初始化
calculation_function1.add(1, c, i, 2)
TextBox1.Text = c
n = Marshal.ReleaseComObject(calculation_function1)
Next
rabiboy 2020-04-10
  • 打赏
  • 举报
回复
引用 10 楼 raynors 的回复:
[quote=引用 9 楼 rabiboy的回复:][quote=引用 8 楼 raynors 的回复:]
你本身的代码那么简单怎么可能有问题,第一反应应该就是DLL出错了.

从字面上分析,就是多次调用产生的多个线程 访问共享内存 产生的冲突.

简单点说.

你两个按钮同时按,肯定会出问题,因为第一次运算还没计算出结果, 第二次运算呼叫过去了,必然会产生某些冲突,除非你函数设计上是多线程且不互相依赖的.

应该要设置一个返回值,表示计算已完成,才能进行下一次呼叫.

感谢回复,您说的这个是指我应该在单次调用完成后先返回一个告知完成的变量再进行下次点击操作么?我实际上在每次调用完在matlab里面写了个弹出窗口通知计算完成,然后我每次点击按钮的操作是在获得计算完成的通知后才再次点击的。[/quote]
监控一下内存使用情况。

如果点一次计算增长,结束后不释放,也会存在内存泄露问题[/quote]
我在调试时发现,有时使用GC.collect回收内存是可行的,有些时候还是会报错。
rabiboy 2020-04-10
  • 打赏
  • 举报
回复
引用 6 楼 irix2008 的回复:
这个一般不是vb.net的问题,封装的matalb组件可能不完善,或者重复调用com部件时是否com部件还在计算中

感谢回复,我在调用dll后完成计算时会返回一个计算结果,我在执行代码时,此时调用完成后若能返回结果且正确,那么我才进行下一次的点击。有什么办法还能跟踪是否看这个com组件执行完了?我理解的它返回了结果后,应该就算是运行完成了。
raynors 2020-04-08
  • 打赏
  • 举报
回复
你本身的代码那么简单怎么可能有问题,第一反应应该就是DLL出错了. 从字面上分析,就是多次调用产生的多个线程 访问共享内存 产生的冲突. 简单点说. 你两个按钮同时按,肯定会出问题,因为第一次运算还没计算出结果, 第二次运算呼叫过去了,必然会产生某些冲突,除非你函数设计上是多线程且不互相依赖的. 应该要设置一个返回值,表示计算已完成,才能进行下一次呼叫.
raynors 2020-04-08
  • 打赏
  • 举报
回复
引用 9 楼 rabiboy的回复:
[quote=引用 8 楼 raynors 的回复:]
你本身的代码那么简单怎么可能有问题,第一反应应该就是DLL出错了.

从字面上分析,就是多次调用产生的多个线程 访问共享内存 产生的冲突.

简单点说.

你两个按钮同时按,肯定会出问题,因为第一次运算还没计算出结果, 第二次运算呼叫过去了,必然会产生某些冲突,除非你函数设计上是多线程且不互相依赖的.

应该要设置一个返回值,表示计算已完成,才能进行下一次呼叫.

感谢回复,您说的这个是指我应该在单次调用完成后先返回一个告知完成的变量再进行下次点击操作么?我实际上在每次调用完在matlab里面写了个弹出窗口通知计算完成,然后我每次点击按钮的操作是在获得计算完成的通知后才再次点击的。[/quote] 监控一下内存使用情况。 如果点一次计算增长,结束后不释放,也会存在内存泄露问题
rabiboy 2020-04-08
  • 打赏
  • 举报
回复
引用 8 楼 raynors 的回复:
你本身的代码那么简单怎么可能有问题,第一反应应该就是DLL出错了.

从字面上分析,就是多次调用产生的多个线程 访问共享内存 产生的冲突.

简单点说.

你两个按钮同时按,肯定会出问题,因为第一次运算还没计算出结果, 第二次运算呼叫过去了,必然会产生某些冲突,除非你函数设计上是多线程且不互相依赖的.

应该要设置一个返回值,表示计算已完成,才能进行下一次呼叫.

感谢回复,您说的这个是指我应该在单次调用完成后先返回一个告知完成的变量再进行下次点击操作么?我实际上在每次调用完在matlab里面写了个弹出窗口通知计算完成,然后我每次点击按钮的操作是在获得计算完成的通知后才再次点击的。
milaoshu1020 活跃的高手 2020-04-04
  • 打赏
  • 举报
回复
同意楼上,.M函数的内容是什么?能不能发出来?
irix2008 2020-04-03
  • 打赏
  • 举报
回复
这个一般不是vb.net的问题,封装的matalb组件可能不完善,或者重复调用com部件时是否com部件还在计算中
rabiboy 2020-03-30
  • 打赏
  • 举报
回复
自己顶一下帖子,别沉
rabiboy 2020-03-29
  • 打赏
  • 举报
回复
引用 3 楼 良朋 的回复:
每次调用之前可否再初始化一次?
因为初始化这个速度比较慢,所以我才把它放在载入窗体的时候。
我现在使用的折中的办法是加入了try,如果catch到内存的错误了,就把它Nothing一下然后GC.Collect,紧接着重新初始化并重新调用。。。
良朋 2020-03-29
  • 打赏
  • 举报
回复
每次调用之前可否再初始化一次?
rabiboy 2020-03-29
  • 打赏
  • 举报
回复
引用 1 楼 贵阳老马马善福专业维修游泳池堵漏防水工程 的回复:
估计是你参数传入进去,结构体或者数组的长度不对,造成内存读取越界

感谢回复,我这样试了一下,每次计算使用相同的参数,进行多次计算后,仍会提示这个“尝试读写受保护的内存”问题。使用相同的参数前面若干次都可以计算并获得正确结果,但是突然后面某一次就报这个错误了。
threenewbee 2020-03-28
  • 打赏
  • 举报
回复
估计是你参数传入进去,结构体或者数组的长度不对,造成内存读取越界

16,552

社区成员

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

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