一行Python 能checkbox实现单选功能什么丧心病狂的功能

关于多线程内存消耗问题_c++吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:269,250贴子:
关于多线程内存消耗问题收藏
我开启一条线程去调用一个函数,函数体是一个for循环,我想统计每次循环中所消耗的内存大小……求大神帮忙
上海张学友、王菲演唱会一站式购票!票品安全且真票!立即订购!
意义何在?单纯统计你自己申请的内存可以把new重载了,循环开始把一个thread local的变量清零,然后new的时候把申请的尺寸加进去,循环结束的时候看加到多少了。不过我的话貌似更关心内存使用的峰值...
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或关于多线程和内存的释放问题
Description of your first forum.
9 篇帖子 & 分页:1 / 1
由 xfeiffer & 星期二, 日 18:17
先把我的线程弄出来吧:
[b]线程中用到的结构体[/b]
&PMsgList=^TMsgL & & & & & & & & & & //消息机制
&TMsgList=[b]record[/b]
& &Style:I & & & & & & & & & & & &//消息类别:0普通消息;1连接;2断开
& &Content:[b]Array[/b][0..9999][b]of [/b]B & & & &//消息内容
& &Length:I & & & & & & & & & & & //消息长度
& &Thread:P & & & & & & & & & & & //Peer的Thread
&[b]end[/b];
[b]声明:[/b]
&TManageMessageThread=[b]class[/b](TThread)
&[b]private[/b]
& &procedure HandleM
& &//一些procedure或者function
&[b]public[/b]
& &myMessage:PMsgL
& &myThread:TIdPeerT
& &myQuery:TADOQ
& &[b]constructor [/b]Create(AStyle:BAQuery:TADOQAMessage:PMsgList);[b]overload[/b];
& &[b]procedure [/b]E [b]override[/b];
& &[b]procedure [/b]T
& &[b]procedure [/b]HandleM
&[b]end[/b];
[b]以下是实现方法:
构造方法[/b]
[b]constructor[/b] TManageMessageThread.Create(AStyle:BAQuery:TADOQAMessage:PMsgList);
[b]begin[/b]
&CoInitialize([b]nil[/b]);//线程种要引用ActiveX控件
&[b]inherited [/b]Create(AStyle);
&FreeOnTerminate:=//线程执行结束后自动释放
&myQuery:=AQ
&myQuery.C
&myMessage:=AM
&myThread:=AMessage.T//TIdPeerThread
[b]end[/b];
[b]procedure [/b]TManageMessageThread.E
[b]begin[/b]
&Synchronize(HandleMessage);//同步执行线程种的数据处理过程
&[red]//WaitF &不知道在这个地方用这句话是否可以起到等待线程结束之后才推出临界区[/red]
[b]end[/b];
[b]procedure [/b]TManageMessageThread.T
[b]begin[/b]
&myQuery.C
&myQuery.F//释放线程中的ADO控件
&myThread.F
&FreeMem(myMessage);//释放指针,传入的AMessage是用GetMem来获取的,所以用FreeMem
&CoUnI//释放ActiveX控件
&[b]inherited[/b];
[b]end[/b];
[b]问题:[/b]
现在线程执行没有问题,但我觉得线程执行完毕之后释放其占用的内存空间的时候有问题,只需要2天时间必定因为内存不足而死机,我查了N多的资料都说那个FreeOnTerminate:=可以释放,但我的为什么不能释放呢?
[b][red]请各位大侠帮帮忙,谢谢!![/red][/b]
由 xfeiffer & 星期四, 日 14:57
由 Wolfding & 星期五, 日 20:33
结构有点儿乱,为什么QueryADO要这么传进来而不是在线程里自己创建自己销毁?为什么消息队列也是这么传进来?为什么是在Terminate方法中释放对象?你调用了Terminate方法吗?Terminate是线程的调度者为了提前中止线程而提供的一个方法,而且你在execute函数里并没有进行循环,无从判断Terminated标志,所以这个函数实际上是无意义的。
你给这个类重载一个Destroy试试,在Destroy里释放,按照你的写法线程执行完毕后是会自动销毁的,但你却没有在线程自身销毁的时候没有把你想销毁的东西销毁掉。
由 xfeiffer & 星期六, 日 08:14
依照你说的,那么那个FreeOnTerminate根本就不起作用了?
那FreeOnTerminate究竟是扮演的什么角色?必须要调用Terminate才能FreeOnTerminate还是当其运行结束时销毁?
由 网中戏 & 星期六, 日 10:07
FreeOnTerminate:=放在E试试。我就放这里的。但是没有试过2天
由 Wolfding & 星期六, 日 15:39
FreeOnTerminate := True的意思,是当线程执行完毕后是否自动释放。
这个属性设置成True或False只在于是否需要你显式地调用FreeAndNil(YourThread)。
你的问题不在于线程有没有被释放,而是下面这些语句没有被执行到:
&myQuery.C
&myQuery.F//释放线程中的ADO控件
&myThread.F
&FreeMem(myMessage);
由 flamboyant & 星期六, 日 16:20
Wolfding说的没没错,应该把Terminate中的语句放入destroy中,或者放入事件onterminate的处理函数中。
tthread中的terminate函数只是设置线程的结束标识(terminated)为true。
由 xfeiffer & 星期日, 日 11:33
OK,确实可以了,我跟踪线程的数量和进程所占用的内存数量,可以看到线程每次创建、销毁时可以看到计数器的变化,而且内存占用也跟以前很不一样,虽然有一些在慢慢增加,但很慢。
由 xfeiffer & 星期日, 日 11:46
增加了Destory的重载,在里面释放创建线程时创建的所有控件,ADO也在线程里面自己创建然后结束时自动销毁,但消息必须得这样通过参数传进去。临界区修改在创建线程时进入,销毁时退出(以前是在主线程里准备创建线程的时候进入,线程resume之后再退出,好像运行起来也没有多大问题,能起到同步的作用),这样运行起来也没有问题了。
9 篇帖子 & 分页:1 / 1扫码下载APP
随时选购服务
需求发布后1小时内收到服务商响应每个需求平均有10个服务商参与95%以上的需求得到了圆满解决所有需求不向雇主收取任何佣金年终总结这么写,升职又加薪
求程序示例:不用try..catch如何实现抓取自身线程内的内存访问异常
求程序示例:不用try..catch如何实现抓取自身线程内的内存访问异常
雇主预算:¥50.00
已收到 2 个服务商的文案稿件
有相似问题想解决?专业顾问来帮助您
通过猪八戒网实名认证,保证身份真实可靠
完成手机认证,保证能随时联系到服务商
参与需求,开始赚钱
第1步:提交您的稿件
第2步:中标后交付作品
第3步:获得赏金
该需求下的优秀交稿
TA的交稿:
精通语言:c&c++&asm尤其擅长:驱动开发,插件开发,游戏辅助开发精&&&&&通&:WinNet以及WinHttp系列开发,webbrowser开发如果是c或c++可联系我
TA的交稿:
用asm直接结构化异常处理,自定义处理函数,然后实现你所要获取的异常信息,查看一些debug的文章就知道了
交易成功的需求
其它工具软件相关需求
&!&在线客服的工作时间为周一至周五 9:00-18:00&&让天下没有难学的技术
《JVM故障诊断指南》之3 —— Java 线程: JVM持有内存的分析
《JVM故障诊断指南》之3 —— Java 线程: JVM持有内存的分析
原文作者:Byron Kiourtzoglou 翻译:梅小西()
前面我们已经讨论过JVM里不同的堆空间,这节我们会给你提供教程,是关于如何从你的活动的应用Java线程中确定它持有多少堆空间,以及在哪里占用。这里有个来自Oracle Weblogic 10.0生产环境的真实案例,它能使你更好的理解分析过程。
我们也会演示这种情况,过多的垃圾收集或者堆空间内存占用问题并不总是由于真实的内存泄露引起,也可能是由于线程执行模型问题和太多的短生命对象引起。
Java线程是JVM基础的一部分。你的Java堆空间内存占用不仅仅是由于静态的和长生命的对象导致,还有可能因为短生命对象。
OutOfMemoryError 问题经常被误认为是内存泄露引起。我们经常忽略错误的线程执行模型和它们持有的JVM里的短生命对象,直到它们的执行完成我们才发现。在这种问题情形下:
o 你“预期”的程序中短生命/无状态对象(XML,JSON数据负载等)被线程持有的时间会变得很长(线程锁争用,大量数据负载,远程系统的慢响应时间等)。
o 最后,这种短生命对象会因为垃圾收集而晋升到长生命空间,比如老年代空间。
o 副作用是会导致老年代空间很快被占满,增加了Full GC(major 收集)的频率。
o 由于这种严重的情况,它将导致更多的GC 垃圾收集,增加JVM暂停时间和最终的“OutOfMemoryError: Java 堆空间”。
o 你的应用此时被停掉,你很疑惑到底怎么回事。
o 最后,你考虑增加Java堆空间或者寻找哪里有内存泄露,你真的找对路了么?
上面这种情况,你应该找到线程执行模型并确定在给定的时间内每个线程需要持有多少内存。
OK我找到了这张图片,但是线程栈大小到底是多少呢?
避免在线程栈大小和Java堆内存占用之间产生混淆是非常重要的。线程栈大小是一种特殊的内存空间,它被JVM用于存储每个方法调用。当一个线程调用方法A,它将这个调用入栈。如果方法A调用方法B,同样也会入栈。一旦方法执行完毕,这个调用便从栈里出栈。
这种线程方法调用会导致Java对象产生,并分配在Java堆里。增加线程栈的大小是没有任何效果的。而调整线程栈大小通常是要处理java.lang.stackoverflowerror错误或者“OutOfMemoryError: unable to create new native thread”错误的时候才会需要。
案例研究和问题环境
下面的分析是基于我们最近调查的一个真实的生产线问题。
1. 改变了用户web接口(使用Google Web Toolkit 和 JSON作为数据负载)后,发现Weblogic 10.0生产环境上出现了某些性能下降。
2. 初始分析发现出现了“OutOfMemoryError: Java heap space”问题并伴有过多的垃圾收集。在OOM出现后自动(XX:+HeapDumpOnOutOfMemoryError)生成了Java堆转储文件。
3. 通过verbose:gc 日志分析确认32-bit HotSpot JVM 老年代空间(1 GB 容量)被完全消耗。
4. 问题发生前和发生时自动产生了线程转储快照。
5. 此时唯一可能减轻问题的方法是在问题发生时重启受影响的Weblogic 服务器。
6. 最终解决了这个问题是将所有的改变回滚。
团队首先怀疑新代码引起了内存泄露。
线程转储分析:寻找嫌疑
第一步我们要做的是对产生的线程转储数据进行分析。这种数据通常会告诉你在JVM堆里面内存分配的罪魁祸首线程。同样的它也会显示任何一个尝试从远程系统发送和接受数据的贪婪或者阻塞的线程。
我们注意的第一个样例是在Weblogic 控制服务器(JVM线程)里观察到的OOM事件和阻塞线程之间有很近的关联关系。下面是找到的原始线程模式:
000337& & [STUCK] ExecuteThread: '22' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "672" seconds working on the request which is more than the configured time of "600" seconds.
如你所见,上面的线程出现了阻塞并且花费了很长时间从远程系统里读和接收JSON响应。一旦我们找到这个样例,接下来是找出它和JVM堆转储分析之间的关联,并且确定这个阻塞线程从堆里占用了多少内存。
堆转储分析:暴露留存的对象!
使用MAT工具来做Java堆转储分析。我们会列出不同的分析步骤,它会允许我们精确查明持有的内存大小和源头。
1.加载HotSpotJVM堆转储文件
2.选择HISTOGRAM 查看并通过ExecuteThread过滤。
* ExecuteThread 是一种Java Class,它被Weblogic内核用于对象的创建和执行*
如你所见,这个图非常有启迪作用。我们可以看到总共210个Weblogic线程被创建。
这些线程总共持有的内存占用是806M。这对于带有1G 老年代的32位的JVM进程来说是非常值得注意的。这个图也告诉了我们这个问题的核心和源于线程自己的内存占有。
3.深入分析线程内存占用
接下来是深入分析线程内存持有。右键点击ExecuteThread 类并且选择“列出所有外部引用的对象”。
如你所见,我们通过线程堆转储分析可以发现“STUCK(阻塞)”线程和大量内存占用有很大关系。这个发现非常意外。
4.线程局部变量鉴别Thread Java Local variables identification
分析的最后一步是需要我们展开几个线程示例并了解内存占用的原始来源。
如你所见,最后一步分析发现根源在于大量的JSON数据响应。通过对转储分析,这个问题可以早点暴露出来,我们发现少量的线程花费太多时间去读取和接收JSON响应,这是大量数据负载的一个明显的症状。
很重要一点,通过方法局部变量创建的短生命对象也会出现在堆转储分析中。然而,其中的一些仅仅能被他们的父线程看到,这是由于他们没有被其他对象引用,比如这个例子。为了找出真正的调用者你或许也需要分析这个线程栈,随后通过代码审查确定最终的根源。
通过这些发现,我们的交付团队能确定最近的JSON错误代码变化的产生,在某些情形下,大量的JSON数据可以达到45M以上。如果环境使用了32位JVM而且仅仅只有1G的老年代,基于这个事实,你就能理解为什么只需要几个线程就足够触发一些性能下降。
这个案例说明,合适的容量预计和堆分析,包括你活动的应用程序的内存占有和Java EE容器线程内存占有都是非常重要的。
译者介绍:
Java工程师,关注JVM,并发编程,喜欢研究Python,Scala,Golang等。
译者相关译文:
原创文章,转载请注明: 转载自本文链接地址:
Latest posts by 深海 ()
Related posts:
(1 votes, average: 5.00 out of 5)
Loading...

我要回帖

更多关于 js实现搜索功能 的文章

 

随机推荐