DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: sdwfdahai
今日帖子: 8
在线用户: 22
导航: 论坛 -> 移动应用开发 斑竹:flyers,iamdream  
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/6/28 23:27:34
标题:
怎样释放服务器上函数申请的内存? 浏览:545
加入我的收藏
楼主: 奇怪,怎么发不了帖子?
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/6/28 23:35:03
1楼: D盾拦截?
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/6/28 23:44:41
2楼: 唉,发不了代码。也就是服务器上写的函数,result引用的内存,在函数调用结束后,会不会释放?
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/6/29 17:56:21
3楼:   Result:=TMemoryStream.Create;
  TMemoryStream(Result).LoadFromFile(FileName);
 
这个流要不要释放呢?
----------------------------------------------
-
作者:
男 keymark (keymark) ▲△△△△ -
注册会员
2020/6/29 18:23:10
4楼: 有Create 有free
除非是个cache。
----------------------------------------------
播客
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2020/6/29 22:11:08
5楼: 最好的习惯哪里分配那里释放。
你用Result返回对象,就要小心翼翼的在外部不使用的时候释放掉。
好的习惯是你在外边创建,传到函数中,函数中LoadFromFile之类的操作内容,外部调用完释放。
或者你用Result返回一些生存期自管理的数据类型也没问题,比如string,动态数组,Interface,或者新增的Managed Record都没问题。
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/6/29 22:25:14
6楼: 写不了代码只能写文字了。从服务器装入文件然后用流传向客户端。客户端调用后,可以释放客户端的流。但服务器 Create了堆对象,这个流不手动释放,系统是肯定不会释放的。客户端反复调用,会消耗大量服务器内存。
解决的办法是,把这个服务器函数装入的流保存在全局的TMemoryStream对象中,在函数体内首先释放流再创建。
或者把函数改成过程,在var 参数中返回流,这客户端释放,但这个不知可行否,因为调用者和被调用者并不在同一内存空间。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/6/29 22:37:55
7楼: 也许,盒子要寿终正寝了,唉。
----------------------------------------------
-
作者:
男 ww1000 (Delphis) ▲▲▲▲△ -
注册会员
2020/7/1 19:04:24
8楼: TMemory Pool ?
----------------------------------------------
阳光总在
作者:
男 ksrsoft (cb168) ★☆☆☆☆ -
注册会员
2020/7/1 19:09:17
9楼: 那就是delphi的DataSnap服务,用到返回流,必然有内存泄漏,天然的
----------------------------------------------
-
作者:
男 nickemma (N.E) ▲▲▲▲△ -
注册会员
2020/7/1 21:25:48
10楼: 服务端不管是为了避免内存泄露或者提高效率,都建议用池来管理。

开启服务端创建内存流对象池,使用的时候从池里面取一个对象,初始化,使用,用完丢回去池里面,程序关闭的时候统一释放池内对象。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/7/1 23:40:16
11楼: datasnap rest本身就是实现了类似内存池的功能。为每个连接创建会话,连接完后销势销毁会话及对象。
别指望关闭服务器程序来释放内存池,因为也许是一年之后的事。
----------------------------------------------
-
作者:
男 nickemma (N.E) ▲▲▲▲△ -
注册会员
2020/7/2 0:21:27
12楼: @sxqwhxq (步惊云)

你说datasnap会自动管理,那你提问意义何在?
另外你看不懂我说的,你喜欢就好。池(pool)为什么要在程序使用过程中释放呢?我管你一年还是十年不关程序,只要程序运行,池就在。
----------------------------------------------
-
作者:
男 littlestone08 (littlestone08) ★☆☆☆☆ -
普通会员
2020/7/16 10:10:06
13楼: @ksrsoft (cb168): 谁告诉你必然有泄漏?完整的开源代码在IDE中可以直接看,不要误导别人。

目前的新的Delphi的DATASNAP中,是由服务自己创建,自动管理生命周期,不存在泄露的风险,前提是用法正确的话.谁释放谁使用这个原则,在新实现的Delphi Datasnap这一框架中是一个特例.

具体应用方法需要自己看源码,跟踪一下才理解得正确.
----------------------------------------------
我和我追逐的梦,擦肩而过
作者:
男 littlestone08 (littlestone08) ★☆☆☆☆ -
普通会员
2020/7/16 10:13:59
14楼:      Result:=TMemoryStream.Create;
  TMemoryStream(Result).LoadFromFile(FileName);
 
这个流要不要释放呢?
----------
如果我没有理解错误的话,你这个是在客户端调用导入的服务端的接口Wapper(暂且这样叫),你调用后,Wapper类中会接管Stream,使用完后,会被Wapper类释放.你不需要手动写代码释放,但你要明白,这个本质上还是你编译出的Exe进行释放的,只不过是你作为参数传递后,Wapper类用完后帮你释放了.
----------------------------------------------
我和我追逐的梦,擦肩而过
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/7/16 13:02:34
15楼: 楼上的提法无法考证。
10.3以后的版本,datasnap/datasnap rest对于内存管理已经很好了,不会再有以前版本的问题了。
10.3中,DSServerClass的LifeCycle设定为Session(这个是默认设置)后,datasnap会用为每个连接建立TServerMethods对象的线程实例,管理线程中数据访问对象、数组、Json对象等。但服务器上申请了流这种二进制大对象,虽然是在线程中申请的,可能datasnap不一定会释放内存,如果不释放,长期工作后必然耗尽服务器内存。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2020/7/16 16:45:13
16楼: 我就想知道,如果你们 Result 一个 流 或 对象。
你们就不关心这个 对象 的调用者,他是怎么释放的吗?
事实上,我用 ROSDK 连 参数的 var out 这些,我都要去看看, RO 的源码,有没有帮我释放。
结果是,如果 客户端 调用 带 var 的 对象。 这种 需要 自己想办法 释放 两个。
而不是一个。
服务器是不需要释放的,因为你没有释放的机会。 RO 帮你释放了。

以上的总结,必须看 源码,才能得到。 你们的 DATASNAP 问题,你们不看源码吗?

14 楼应该是看过源码了。楼主 不相信他。但是 我不看源码,我也不相信别人。
当我需要的时候,我必然去看源码,看完,我就会说,原来 14 楼说的对啊。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2020/7/17 8:39:28
17楼: 楼上,如果函数和调用者在同一片内存空间,由调用者释放,是很容易做的事,甚至可以不用result传流,而用var 参数,调用者根本无须复制流,调用与被调用者共同引用一个流对象即可。
但datasnap服务器和调用者不在同一内存空间,流必须从服务器复制到客户端,所以没可能由调用者释放。
我现在把M:TMemoryStream定义在TServerMethods对象的public内,然后在Function PassStreamToClient中第一句即删除:FreeAndNil(M);
----------------------------------------------
-
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2020/7/17 20:27:54
18楼: delphi的datasnap的返回流,是会被自动释放的

但是,如果是用indy(TCP/HTTP EXE)来做server, 在网络抛异常的时候,result的释放代码就会被跳过造成内存泄漏。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行50.78125毫秒 RSS