|
|
导航: |
论坛 -> 发布代码
斑竹:liumazi,ruralboy |
|
作者: |
|
2019/4/1 21:51:35 |
标题: |
delphi解决运行程序占用内存解决办法 |
浏览:3807 |
|
加入我的收藏 |
楼主: |
自己用delphi2010开发了个邮件群发软件,以前是连续工作几天程序就不响应了,最近几天开机一个晚上第二天起来就发现程序无响应了。 今天终于想出了解决的办法,每次系统自动发邮件之后释放内存,运行OK! //释放空闲内存模块 if Win32Platform = VER_PLATFORM_WIN32_NT then begin SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF); forms.Application.ProcessMessages; end;
----------------------------------------------
- |
作者: |
gmxyb (gmxyb) |
★☆☆☆☆ |
-
|
普通会员 |
|
2019/4/1 22:00:52 |
1楼: |
我觉得这个只是 治标不治本。
----------------------------------------------
-
|
作者: |
|
2019/4/1 22:42:45 |
2楼: |
这个应该与程序不响应没有关系。
----------------------------------------------
-
|
作者: |
|
2019/4/2 0:24:36 |
3楼: |
如果你的程序要连续工作,那应该从资源分配、线程调度等一系列问题上去注意你的代码。
这个函数根本就没什么卵用,这个函数的作用只是把进程暂时不用的内存空间转移到虚拟内存去了而已。
一个7*24的服务端程序没什么好写的。
----------------------------------------------
--
|
作者: |
|
2019/4/2 9:09:30 |
4楼: |
无响应根本和你运行几天没有关系,你看看代码里有什么地方阻塞了。
----------------------------------------------
简单做人,认真做事。
|
作者: |
hs_kill (lzl_17948876) |
★☆☆☆☆ |
-
|
普通会员 |
|
2019/4/2 9:16:50 |
5楼: |
如果SetProcessWorkingSetSize能保证你一直工作不出错, 只能说明你以前的代码内存管理有问题, 该释放的地方没释放
----------------------------------------------
http://www.cnblogs.com/lzl_17948876/
|
作者: |
|
2019/4/2 11:06:03 |
6楼: |
这个函数只是把你的内存交换到磁盘,可用物理内存增加了。但是程序会变慢。 而且你的程序有内存泄露的话最终还是会死掉的
----------------------------------------------
武稀松http://www.raysoftware.cn
|
作者: |
joman (joman) |
▲▲▲▲▲ |
-
|
普通会员 |
|
2019/4/3 11:39:41 |
7楼: |
嗯,我那个框架也加入这个机制了,不过感觉不是解决问题的好方案 根本问题是资源释放问题,内存不断增大肯定是资源没释,还是做下内存泄露检测吧
----------------------------------------------
DelphiWeb开发方案(开源):https://gitee.com/pearroom/DelphiWebMVC
|
作者: |
dmzn (dmzn) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2019/4/3 16:12:04 |
8楼: |
所有需要长时间运行的服务,都需要网络连接池 数据库连接池 对象连接池这种能复用资源的东西.
----------------------------------------------
生活愉快.
|
作者: |
|
2019/4/15 3:22:23 |
9楼: |
内存泄漏嘛。作为程序员,写代码细心一点,就不会有的。遵循一些基本原则,就不容易出错。
----------------------------------------------
-
|
作者: |
|
2019/4/15 9:15:54 |
10楼: |
这种情况还不简单,多写个程序,定时把群发软件关了再重启。简单有效,简直完美。
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
|
2019/4/15 9:24:39 |
11楼: |
解决内存等资源耗尽最完美的方案不是靠算法,而是允许系统整体或者部分用到一定程度就关闭重启,算法永远找不到最完美的算法而且成本奇高。
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
gmxyb (gmxyb) |
★☆☆☆☆ |
-
|
普通会员 |
|
2019/4/15 9:53:35 |
12楼: |
。。。按照11楼的说法,操作系统也不需要靠算法,反正不行了就重启嘛~
----------------------------------------------
-
|
作者: |
|
2019/4/15 20:22:06 |
13楼: |
xxxx:网管,电脑卡了! 网管:重启!
重启包治百病!
----------------------------------------------
-
|
作者: |
|
2019/4/15 23:34:22 |
14楼: |
12楼,操作系统面对来自应用的内存请求比较简单,但应用面对来自其内部的内存请求就复杂多了。所以,你说的啥意思? 我说的是一种新的策略,它的大概思路就是: 编程语言(比如:JAVA)设立“强制回收类”,这类有以下特点: 1. 给这类的实例分配一内存块,这类以及组成部分所有的内存分配都从这内存块里分配。 2. 允许JVM监控内存块的使用情况,一旦糟糕可以强制释放这类实例并撤销内存块,然后重新创建类实例。 3. 从强制释放到创建新实例,期间外部对这类以及其组成部分的访问都要挂起。
这策略的优势很明显: 1. 不需要很复杂的算法就能达到非常好的内存管理。 2. 即使系统访问压力很大的情况下,内存管理表现得很轻松很稳定。
劣势: 1. “强制回收类”适合逻辑复杂但外界对它的状态要求很少。其实很多大型系统的核心组件都适合用这种类编写。 2. 外部要应对访问这种类实例以及其组成部分会出现访问失败的情况。
大概想到这些。
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
gmxyb (gmxyb) |
★☆☆☆☆ |
-
|
普通会员 |
|
2019/4/16 8:28:20 |
15楼: |
真是个钢精。。不知道你想表达什么。。
jvm 垃圾回收算法很简单是不是? jvm 自身的垃圾回收不是靠算法就是暴力回收是不是? Java 程序就可以随便写不会存在内存泄漏是不是? jvm 经常崩溃、oom,那就再多写个程序,把jvm重启一下就好是不是? 。。。
----------
10楼:“多写个程序,定时把群发软件关了再重启”。。
我就问下10楼,你“多写”的那个程序必须要长期运行的吧?它自己也会有卡死的可能性吧?卡死了咋办?
我知道,你的答案肯定是:简单,再多写一个程序,负责重启前面那个!
我说的对吧?!
----------------------------------------------
-
|
作者: |
|
2019/4/16 8:59:08 |
16楼: |
掩耳盗铃
----------------------------------------------
[alias] co = clone --recurse-submodules up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
|
作者: |
|
2019/4/16 9:10:40 |
17楼: |
顶 1 3 6 9 15 楼。
----------------------------------------------
(C)(P)Flying Wang
|
作者: |
|
2019/4/16 9:11:47 |
17楼: |
…… 被禁用帐号,帖子内容自动屏蔽! ……
----------------------------------------------
该账号是个傻逼
|
作者: |
|
2019/4/16 10:18:28 |
18楼: |
楼上 SYSTEM SHCEDULER 也卡死了,怎么办?
----------------------------------------------
(C)(P)Flying Wang
|
作者: |
|
2019/4/16 10:45:54 |
19楼: |
重点不是应该检查为啥内存不释放吗?
除非以下情况: 1、懒 2、难
检测/自动重启或者强制释放,如果要求不高,其实并没有什么问题。
----------------------------------------------
-
|
作者: |
gmxyb (gmxyb) |
★☆☆☆☆ |
-
|
普通会员 |
|
2019/4/16 10:49:04 |
18楼: |
17楼,我知道,其实你说的意思是:
这只是个小程序,并不值得花心思去弄得完美无瑕。。。
楼主发的明白人都知道这是掩耳盗铃,上面大牛们指出,只是为了避免被这个误导。
至于解决问题,反正能用就好了,能忽悠住给你发工资的人也是你的本事。
----------------------------------------------
-
|
作者: |
|
2019/4/16 11:08:49 |
20楼: |
…… 被禁用帐号,帖子内容自动屏蔽! ……
----------------------------------------------
该账号是个傻逼
|
作者: |
gmxyb (gmxyb) |
★☆☆☆☆ |
-
|
普通会员 |
|
2019/4/16 11:12:11 |
21楼: |
看出来了,,反正有问题都不是自己的问题,都推给别人就对了 ~
----------------------------------------------
-
|
作者: |
|
2019/4/16 12:03:17 |
22楼: |
回看!!!!!!六楼吧 没啥好说的。 不过我看到的说法是 微软有算法 用来清理你 某个周期 没用到的内存存盘 和这个函数大致思维一样。。只是有个计数??。。。呵呵, 也许我理解错了。
----------------------------------------------
[alias] co = clone --recurse-submodules up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
|
作者: |
|
2019/4/16 13:51:43 |
23楼: |
to gmxyb: 不要激动,大家都有点文化,摆事实讲道理就行了。如果吵架有用,人类都进化成个个都是大嗓门了。这里有两件事:
第一件,楼主的问题,我给出了很高性价比的办法,无论是打工还是自己做老板都非常合适,半天时间写个小程序。这程序或许不能长期运行,1个月应该可以,半年或许可以,足够了。说完美可能会刺激某些人的神经。如果有人说这办法我学不到东西,那是你的事。
第二件,18楼的“检测/自动重启或者强制释放,如果要求不高,其实并没有什么问题。”,看不到我说的价值。我恰恰在说有比现在主流更好的解决策略。 内存回收机制难在哪里? 以JVM为例,难在上面跑的程序内存申请和使用的情况很复杂,复杂在申请的内存大小、申请的时机、申请的频率、使用的时长、如果有共享还要考虑共享的使用。如果都像操作系统面对应用的内存申请那么简单就不难解决了。 据我所知,现在主流的解决方法就像JVM那样,把可用内存划分成大小相等的块,分配、没用就回收、碎片多就整理。然而,一旦系统访问压力大同时回收碎片整理任务又重,难免会影响系统性能。 而我提出的是通过“分而治之”的策略,JVM再也不用面对复杂的内存申请使用情况。JVM一旦检测到某个内存块碎片很糟糕,则重新创建一个类实例,然后释放旧的类实例,替换即可;比回收整理明显轻松很多--cpu轻松了,开发人员也轻松。 这方法需要开发人员配合,在设计上做出调整才能发挥作用,我觉得大多数都可以改成我说的样子。 有兴趣的不妨研究一下。如果我做JVM肯定用这策略。
---------- 最后再说一次,说什么都好,要摆事实讲道理。虽然这在中国不那么适用,但在技术领域适用吧
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
|
2019/4/16 13:57:52 |
24楼: |
原来各位都是 JAVA 开发啊。 我们 DELPHI 的 移动端 未来要取消 ARC 了。 桌面端,也从来不支持 ARC。 没有 ARC,也就不存在自动回收, 辛苦 各位 自己写 free 了。 也许懒一点,不写 free。给自己的 exe 设置一个 大内存也行吧。 反正 只要 保证 内存用完之前 exe 就退出了。也没啥大不了的(不退?杀掉!杀不掉?重启呗,总会有办法的)。 比如 a: TStream; begin a := TMemoryStream.Create; a.size := 1024; end; 这种代码,猴年马月才能耗光内存。 1024*1024*1024 就不一样了。
----------------------------------------------
(C)(P)Flying Wang
|
作者: |
|
2019/4/16 14:10:43 |
25楼: |
楼上,不要用极端的例子去佐证自己的观点,这是很不好的习惯。 就像gmxyb,长期是多久,50年 30年,相关的人在不在还是个问题。 用这些概率很低的例子去支撑自己的观点,为了什么?
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
|
2019/4/16 14:27:33 |
26楼: |
也不知道谁极端。 我们 DLEPHI 论坛,居然歪楼到 JAVA 了! 关键是,你这是 硬歪啊。 我们都没人讨论 JAVA,你强行拐弯啊。
----------------------------------------------
(C)(P)Flying Wang
|
作者: |
|
2019/4/16 14:38:45 |
27楼: |
如果delphi按我说的策略提供支持,相信开发的服务端比java还稳定,arc那些都不需要了
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
|
2019/4/16 17:39:19 |
28楼: |
我本来就不认为Delphi开发的服务端稳定性会比Java的差
----------------------------------------------
-
|
作者: |
|
2019/4/16 17:41:40 |
29楼: |
@wuxi15 (似水·流年): 这论坛很多人都不这样认为吧?
----------------------------------------------
虽千万人吾往矣!
|
作者: |
|
2019/4/16 21:08:00 |
30楼: |
太不厚道了,要骗我们学其他语言搞服务端,学go怎么也比java好吧,学java不是从这个坑跳到另外一个坑么
----------------------------------------------
-
|
作者: |
|
2019/4/22 4:31:45 |
31楼: |
不是有try...finally...end和OnCreate及OnDestroy事件可以用来管理内存吗?为什么都不用?硬把Delphi当爪哇使?
----------------------------------------------
-
|
作者: |
|
2019/4/22 5:44:42 |
32楼: |
JAVA 那种垃圾回收,本来就是为低水平的程序员开发的。
企鹅家的服务器端代码,现在还好多用 C++ 呢。一样干。
----------------------------------------------
-
|
作者: |
|
2019/4/24 15:19:24 |
33楼: |
之前Delphi7写过发送邮件的程序,在一台服务器上跑(配置忘了),每天发送将近250万的邮件,没有出过类似问题。当时最大的问题是有个吸铁石的电邮,服务非常慢,影响了发送效率。
----------------------------------------------
-
|
作者: |
|
2019/4/25 22:21:54 |
34楼: |
如果delphi有自动内存回收机制,我一定会用的。但是,在没有的情况下,我会小心的将自己申请的内存用完后还回去,道理很简单:有借有还,再借不难!
----------------------------------------------
-
|
作者: |
|
2019/4/25 23:17:01 |
35楼: |
34 楼,Delphi 实现内存自动回收不难啊。几十行代码搞定。俺在 03 年就已经实现了。不外乎就算创建对象,对象缓冲,对象释放嘛。基于 Delphi 的接口机制,你的代码完全可以不用管对象的释放问题。没人用了,它自己回缓冲池。缓冲池装满了,自己释放。
----------------------------------------------
-
|
作者: |
kuei (kuei) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2019/4/26 8:28:59 |
36楼: |
说这么多.... 养成良好敲代码习惯不就好
要当程序员,就不要太懒,勤快一点 变数、物件,自己宣告,自己释放
----------------------------------------------
-
|
作者: |
|
2019/4/26 22:28:14 |
37楼: |
JVM和LLVM都属于社会分工细化的产物,其系统架构具有战略优势,腾讯不用肯定是他们自己的原因。 delphi的接口机制,不好啊。 多线程不行、ref减一时机不对又会出问题,不说了。
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
|
2019/4/26 22:48:41 |
38楼: |
谁说 delphi 的接口机制多线程不行。俺一个程序有20多个线程,里面一堆接口实例,可能同时存在的有100来个,不停地从缓冲池拿出来用,用完它自己回到缓冲池都无需程序去管,连续跑几天也不会有内存泄漏。代码架构也很舒服,因为无需应用层代码去管对象的创建和释放。实际上,就是所谓的类工厂,对象缓冲池这些概念在 Delphi 里面的实现。
----------------------------------------------
-
|
作者: |
|
2019/4/27 12:52:57 |
39楼: |
不行的意思主要指排错困难,我尽量同一接口在一个线程里用。因为delphi的接口机制里,接口变量没用,refcount就减一,但实例变量没用,对refcount没影响。如果多个线程用到同一实例变量以及其实现的接口,接口用完了,实例释放,但有线程还在用实例变量,排错就有一定困难。
delphi的接口要用好得这样: Type IGoodInterface = interface(IInterface) ['{4A8C144E-07B9-4357-8BF0-EE57D2F69888}'] procedure ReleaseInIdle; //通知实例可以释放了 end; TGoodInterfaced = class(TInterfacedObject, IGoodInterface) private mSelf:IGoodInterface ; procedure ReleaseInIdle; protected public constructor Create() ; end;
constructor TGoodInterfaced.Create() ; begin Inherited Create() ; mSelf:=Self as IGoodInterface ; end;
procedure TGoodInterfaced.ReleaseInIdle() ; begin //释放前做准备 .... // mSelf:=nil ; end ;
///---------- 那么每个TGoodInterfaced的实例和其子类的实例,创建后,统一在需要释放时用以下方式释放: (实例变量 as IGoodInterface).ReleaseInIdle() ; 或者 (接口变量 as IGoodInterface).ReleaseInIdle() ;
这样在绝大多数情况下,只要释放的时机选得好,就没有问题。
---------- 楼上说的,适合松散的结构,在紧密结构里的实例,释放前一般都要向外放出通知,告诉其它模块这模块不工作了。有时要控制模块不工作的顺序,可以不用接口但设计上又不方便,这就是delphi接口机制不好的地方。
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
|
2019/4/27 16:58:19 |
40楼: |
[如果多个线程用到同一实例变量以及其实现的接口,接口用完了,实例释放,但有线程还在用实例变量,排错就有一定困难]
楼上的,既然要用接口,就不要用对象实例。不要想两头都抓住。
Delphi 给了一个比较麻烦的东西,就是 TComponent,如果有地方用了对象实例同时有地方用了接口,接口释放完了,对象实例也不会被释放。这不是好事。
牢记基本规则,代码就会很简单。基本规则就是:用接口的地方,不要用对象实例。
----------------------------------------------
-
|
作者: |
|
2019/4/28 22:15:33 |
41楼: |
pcplayer: 其实你所提的对象缓冲池,起码包括两个问题: 1. 外部如何使用池里的对象所提供的功能。 2. 池里对象生存期的管理。即何时创建、外部用完后是缓存还是释放等。
问题1适合用delphi的接口,因为写起来简单。问题2是不受问题1影响的。 一个问题一个unit解决,本应该分在两个unit里,我相信你都耦合到一个unit上了,对吧?
所以,你之所以有这规则,是因为问题2逻辑简单,一旦池里的对象的生存期管理复杂,就容易出问题。当然,逻辑不复杂,怎么写都行。
------- 现在delphi的接口机制既不能完全满足面向对象里对接口设计的需要,自动回收也解决不好;但总比没有的好就是了。
----------------------------------------------
软件是什么,相信很多人都说不清。
|
作者: |
|
2019/4/29 14:08:01 |
42楼: |
一个帖子吵了一个月,各位都是神仙级的。。
----------------------------------------------
--
|
作者: |
|
2019/4/29 14:12:18 |
43楼: |
程序员的讨论能叫吵吗?
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
|
作者: |
|
2019/4/30 15:00:22 |
44楼: |
神一样的解决方案, 和连神都想不出来的回复论点
----------------------------------------------
-
|
|