c#程序如何避免c 程序内存泄漏漏

为什么我的C#方法对用户对象的内存泄漏_百度知道
为什么我的C#方法对用户对象的内存泄漏
我有更好的答案
在NET和它的垃圾收集器将只处理一个对象,如果它是一个管理对象。非托管对象必须处理掉你。那这是不是由如果offed方案这些对象自身控制资源的非托管对象可以,你有很多的垃圾,在没有其他进程就能够处理。您可能要检查这个问题了:什么由"管理和QUOT;比及QUOT;非托管和QUOT; NET中的资源呢
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。&>&Net程序的内存泄漏
Net程序的内存泄漏
上传大小:156KB
讲.net内存泄露的相关培训资料,公司内部资料,很实用的哦
综合评分:0
下载个数:
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有0条
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
Net程序的内存泄漏
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
举报的资源分:
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*详细原因:
Net程序的内存泄漏程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
Android研究院之内存泄漏调试学习与总结(二十二)
Android研究院之内存泄漏调试学习与总结(二十二)
围观8898次
编辑日期: 字体:
开始学习啦,吼吼,小马很尽量写清楚自己想的与学习到的知识,希望大家不要嫌啰嗦,仔细看下小马描述与扩展的知识,一定能学到东西的!
好了,先简单说下,大家有或经常碰到OOM的问题,对吧?很多这样的问题只要一出现相信大家的想法跟小马的一样,就是自己的应用:优化、优化、再优化!而且如果出现类似于OOM这样级别的问题,根本就不好处理,LogCat日志中显示的信息仅仅是OOM,并不会给你提示如何解决的方法或思路,因为引起OOM的原因是你应用的问题,不是系统问题!应该想下,在优化之前找到需要优化的地方,再去做优化操作不是更直接吗?相信大多数朋友应该经常听过或使用Jnuit调试吧,好了,废话不多说,今天小马就跟大家一起来学习总结下OOM的调试方法,来找到需要优化的地方,要知道OOM也是可以一步步调试的:
首先,先一起来做些小小的知识铺垫:
Android(Java)中常见的容易引起内存泄漏的不良代码:
1. 查询数据库没有关闭游标
程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会复现内存问题,这样就会给以后的测试和问题排查带来困难和风险示例代如下码:
1234567891011121314151617181920
Cursor cursor = getContentResolver().query(uri ...);if (cursor.moveToNext()) {&&... ...&&} 修正示例代码:Cursor cursor = null;try {&&cursor = getContentResolver().query(uri ...);&&if (cursor != null && cursor.moveToNext()) {&&... ...&&&&}} finally {&&if (cursor != null) {&&try {&&&&cursor.close();&&} catch (Exception e) {&&//ignore this&&}&&}}
2. 构造Adapter时,没有使用缓存的 convertView ,这个问题小马上一篇:ListView加载数据原理及优化总结(二十一)中已经讲过了,大家可以回过头看下
3. Bitmap对象不在使用时调用recycle()没有及时释放
如果一个Bitmap对象比较占内存,当它不在被使用的时候,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存
4.没有及时释放对象的引用
简单举个例子:比如两个Activity之间传递的Context 或其它的自定义对象,使用完后必须立即释放 即:Activity =
Context = Object =可以的话在这释放对象之后通知系统来回收:System.gc();这样最好了!
Android主要应用在嵌入式设备当中,而嵌入式设备由于一些众所周知的条件限制,通常都不会有很高的配置,特别是内存是比较有限的。如果我们编写的代 码当中有太多的对内存使用不当的地方,难免会使得我们的设备运行缓慢,甚至是死机。为了能够使得Android应用程序安全且快速的运行,Android 的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程演变过来的,也就是说每个应用程序都是在属于自己的进程中运行的(问题一:这个地方小马怎么知道是在属于自己的进程中运行的?大家继续,答案小马会在下面详细介绍)。一方面,如果程序在运行过程中出现了内存泄漏的问题,仅仅会使得自己的进程被杀掉,而不会影响其他进程(如果是system_process 等系统进程出问题的话,则会引起系统重启)。另一方面Android为不同类型的进程分配了不同的内存使用上限,如果应用进程使用的内存超过了这个上限, 则会被系统视为内存泄漏,从而被杀掉
下面小马来解释下问题一:”每个应用程序都是在属于自己的进程中运行的”这句话,对于这句话,大家只记住一点:“当一个程序第一次启动的时候,Android会启动一个LINUX进程和一个主线程。默认的情况下,所有该程序的组件都将在该进程和线程中运行。”~^_^
O_O !!!
同时,Android会为每个应用程序分配一个单独的LINUX用户。Android会尽量保留一个正在运行进程,只在内存资源出现不足时,Android会尝试停止一些进程从而释放足够的资源给其他新的进程使用, 也能保证用户正在访问的当前进程有足够的资源去及时地响应用户的事件。Android会根据进程中运行的组件类别以及组件的状态来判断该进程的重要性,Android会首先停止那些不重要的进程。按照重要性从高到低一共有五个级别就是我们常说的:前台进程、可见进程、服务进程、后台进程、空进程(此处概念略,大家自己查)
还有个小扩展:当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。Android的UI是单线程(Single-threaded)的。为了避免拖住GUI,一些较费时的对象应该交给独立的线程去执行。如果幕后的线程来执行UI对象,Android就会发出错误讯息 CalledFromWrongThreadException。以后遇到这样的异常抛出时就要知道怎么回事咯!
好了,铺垫知识就写这么多了,下面直接进入主题了:OOM调试
方式一:使用内存监测工具 DDMS –& Heap:(真机、模拟器均可使用)
1. 启动eclipse后,切换到DDMS透视图,并确认Devices视图、Heap视图都是打开的,没打开的直接Window&ShowView&自己选;
2. 将手机通过USB链接至电脑,链接时需要确认手机是处于“USB调试”模式
3. 链接成功后,在DDMS的Devices视图中将会显示手机设备的序列号,以及设备中正在运行的部分进程信息;
4. 点击选中想要监测的进程,如果在进程列表中未出现你的进程的话随便选中一条让Device一排的工具处于可用状态,再点击下Update Heap让其自动找到我们跑的应用的进程,比如小马临时跑的两个应用进程如图;
5. 点击Heap视图中的“Cause GC”按钮;
6.点击Cause GC之后就可以看到我们应用的内存情况如下图:
a) 点击“Cause GC”按钮相当于向虚拟机请求了一次gc操作;
b) 当内存使用信息第一次显示以后,无须再不断的点击“Cause GC”,Heap视图界面会定时刷新,在对应用的不断的操作过程中就可以看到内存使用的变化;
c) 内存使用信息的各项参数根据名称即可知道其意思,不知道具体意思的朋友自行用工具(有道、词霸查去)
知道工具使用了,那么如何才能知道我们的程序是否有内存泄漏的可能性呢。这里需要注意一个值:Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,如果大家想要看“Total Size”是分配的具体信息可以点击“data object这一行来查看详细信息,如下图”(大家看不清楚的点击看大图)
一般情况下,在data object行的“Total Size”这个值的大小决定了是否会有内存泄漏。可以这样判断:
a) 不断的操作当前应用,同时注意观察data object的Total Size值;
b) 正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况,所以说虽然我们不断的操作会不断的生成很多对 象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平;
c) 反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落,随着操作次数的增多Total Size的值会越来越大,
直到到达一个上限后导致进程被杀掉。
Android为应用进程分配的内存上限如下所示:(下面这些是小马网上查到的,小马不懂下面的语法,但知道有限制这么一回事就够了,此处不研究下面的代码)
位置: /ANDROID_SOURCE/system/core/rootdir/init.rc 部分脚本
# Define the oom_adj values for the classes of processes that can be
# killed by the kernel. These are used in ActivityManagerService.
setprop ro.FOREGROUND_APP_ADJ 0
setprop ro.VISIBLE_APP_ADJ 1
setprop ro.SECONDARY_SERVER_ADJ 2
setprop ro.BACKUP_APP_ADJ 2
setprop ro.HOME_APP_ADJ 4
setprop ro.HIDDEN_APP_MIN_ADJ 7
setprop ro.CONTENT_PROVIDER_ADJ 14
setprop ro.EMPTY_APP_ADJ 15
# Define the memory thresholds at which the above process classes will
# be killed. These numbers are in pages (4k).
setprop ro.FOREGROUND_APP_MEM 1536
setprop ro.VISIBLE_APP_MEM 2048
setprop ro.SECONDARY_SERVER_MEM 4096
setprop ro.BACKUP_APP_MEM 4096
setprop ro.HOME_APP_MEM 4096
setprop ro.HIDDEN_APP_MEM 5120
setprop ro.CONTENT_PROVIDER_MEM 5632
setprop ro.EMPTY_APP_MEM 6144
# Write value must be consistent with the above properties.
# Note that the driver only supports 6 slots, so we have HOME_APP at the
# same memory level as services.
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15
write /proc/sys/vm/overcommit_memory 1
write /proc/sys/vm/min_free_order_shift 4
write /sys/module/lowmemorykiller/parameters/minfree 96,44
# Set init its forked children’s oom_adj.
write /proc/1/oom_adj -16
d) 此处以com.xiaoma.www进程为例,在我的测试环境中com.xiaoma.www进程所占用的内存的data object的Total Size正常情况下稳定在0.8~1.0M之间,而当其值超过3~5M每次启动应用该值不稳定的时候进程就会被系统杀掉啦!
内存监测工具 DDMS –& Heap
使用内存分析工具 MAT(Memory Analyzer Tool)
(一) 生成.hprof文件 (生成很简单,直接点击Device 工具栏中的 Dump HPROF file即可生成)
(二) 使用MAT导入.hprof文件
(三) 使用MAT的视图工具分析内存
总之,使用DDMS的Heap视图工具可以很方便的确认我们的程序是否存在内存泄漏的可能性。这个地方顺带着也简单的说一下,如果大家想要跟踪更详细的内存是怎样分配的话,可以学着使用下Windows&ShowView&Allocation Tracker工具来定位你的内存什么时候被什么东西占用了,是bundlea或HashMap或ArrayList焦点或是其它的什么占用了这些都可以在这个插件中查看到的,简单的使用方法就是:选中Device进程列表中的某一个进程,让Allocation Tracker里面的跟踪工具处于可用状态,点击Stop Tracking来跟踪程序,过一定时间后,点击Get Allocations来获取内存分配的消息就可以查看更为详细的内存分配情况了,如下图:
Allocation Tracker这个小工具比较简单, 小马在这个地方不一一说明了,想学的朋友们自己点击看看就会知道里面的参数是什么意思了…..^_^……..最后,还是一样,小马在内存管理方面还要学的东西很多,如果文章中小马有讲的不清楚或不足之处,大家留言批评并提出更好的建议,小马一定及时改进,在此先谢谢大家啦,吼吼学习学习!大家加油,一起进步!!!
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:小马果
【誓言、会老】…【承诺、会变】…【目标、遥远】…【选择、不后悔】…【对自己要狠】…所有动力,源自兴趣,爱编程,更过编程的过程.....
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!我有以下代码:MemoryStream foo(){
MemoryStream ms = new MemoryStream();
//write stuff to ms
void bar(){
MemoryStream ms2 = foo();
//do stuff with ms2
}我分配的MemoryStream是否有可能在以后无法处理?我有一个同行评审坚持我手动关闭了这个,我找不到信息告诉他他是否有一个有效的点。
时间:17年05月06日原作者:
共13个回答
如果东西是一次性的,你应该总是释放它。 你应该在 bar() 方法中使用一个使用语句来确保ms2被处理。它最终会被垃圾回收器清理,但它总是很好的做法。 如果在代码上运行 FxCop,它将把它标记为警告。
你不会泄露任何内容- 至少在当前的实现中。调用Dispose不会清除MemoryStream所使用的内存。 会阻止你流后可行的读/写调用调用,这可能会或可能不会对你有用。如果你绝对相信你绝不想从memorystream另一种流,它不是要做你任何伤害不叫处理。 然而,它通常是良好的实践部分是因为如果你曾经改变使用不同的流,你不想得到被 hard-to-find Bug 因为你选择了一条简单的出路。 ( 另一方面,有YAGNI参数。)另外一个原因是,一个新的实现可能会引入资源,它将释放释放。
是的有泄漏,这取决于你如何定义泄漏,后来你的意思。。如果泄漏你的意思"内存仍然分配,无法使用,即使你已经使用它"和后者意思随时调用处理后,然后然后是的可能有泄漏,尽管它不是永久性的( 例如 。 对于应用程序运行时的生命周期) 。免费使用的内存管理memorystream,需要unreference,取消你的参考,所以马上就有资格获得垃圾收集。 如果你没有这么做,那么你就会在使用它时创建一个临时的泄漏,直到你的引用超出了范围,因为在这个过程中内存无法分配。使用语句( 通过调用 dispose )的好处是你可以在使用语句中声明引用。 当使用语句结束时,不仅调用 dispose,而且你的引用会超出范围,有效地取消引用,使你的对象能够立即进行垃圾收集,而不需要你记住编写"reference=null"代码。虽然没有立即发现unreference是一个典型的"永久"内存泄漏,但它确实有同样的效果。 例如如果你保留对 MemoryStream ( 即使在调用dispose之后)的引用,并且在你的方法中进一步向下,你将尝试分配更多的内存。 still-referenced内存流使用的内存对你不可用,除非你取消了引用或者它超出了范围,即使你调用了dispose并使用了它。
这已经回答了,但是我只需要添加好的信息隐藏原理,就意味着你可能会在未来的未来需要重构:MemoryStream foo()
MemoryStream ms = new MemoryStream();
//write stuff to ms
}到:Stream foo()
}这强调调用者不应该关心返回的流类型,并使更改内部实现成为可能( 比如 。 当模拟单元测试时。然后,如果你没有在bar实现中使用 Dispose,则需要有麻烦:void bar()
using (Stream s = foo())
//do stuff with s
所有流都实现 IDisposable 。将内存流包装在using语句中,并且你将会很好地。 使用块将确保你的流已经关闭并在任何情况下都被释放。无论你什么时候调用 Foo,你都可以使用( MemoryStream ms = Foo ( ) ),我认为你仍然应该。
不需要调用 .Dispose() ( 或者用 Using 包装) 。原因你叫 .Dispose() 尽快释放资源。想想,比如堆栈溢出服务器,我们有一个有限的内存集和成千上万的请求。 我们不想等待预定的垃圾收集,我们想尽快释放这个内存,以便它可以用于新的传入请求。
你不会泄露内存,但是你的代码审阅者是正确的,表明你应该关闭你的流。 这样做是礼貌的。你可能会泄漏内存的唯一情况是当你意外离开对流的引用时,并从不关闭它。 你仍然没有内存泄露,但不必要地延长的时间你声称是使用它。
我建议将 bar() 中的MemoryStream包装在 using 语句中以保持一致性:现在,MemoryStream不能释放 .Dispose() 上的内存,但在将来可能会发生这种情况,或者你( 或者你公司的其他人) 可能会用你自己的自定义MemoryStream替换它。它有助于建立一个模式在你的项目,以确保所有流处理--线更坚定地说"必须释放所有流"代替"必须释放一些流,但某些流不一定要"。如果你更改了代码以允许返回其他类型的流,则需要将它的更改为 dispose 。我经常做的另一件事类似 foo() 当创建并返回一个idisposable是确保任何失败构建的对象和 return 之间被一个异常,处理对象,和rethrows例外:MemoryStream x = new MemoryStream();
//... other code goes here.. .
//"other code" failed, dispose the stream before throwing out the Exception
x.Dispose();
如果对象实现 IDisposable,则必须在完成后调用。dispose方法。在某些对象中,Dispose意味着与Close相同,反之亦然,在这种情况下,要么是好的。现在,对于你的特定问题,不,你不会泄露内存。
我不是. NET 专家,但也许这里的问题是资源,即文件句柄,而不是内存。 我猜垃圾收集器最终会释放流,并关闭句柄,但我认为最好是将它的显式关闭,以确保将内容清空到磁盘。
Copyright (C) 2011 HelpLib All rights reserved. &&你的IE浏览器版本过低,为了提升体验
建议升级到IE10以上或使用Chrome、搜狗等浏览器
不会啊,\0不是内存里面就是\0像C里面字符串的结尾,这里面在内存里有的是转码表示的,所以,不出现你说的问题
不会string s = new String(c);这个构造函数会帮你加上的,记住,托管代码不会有内存泄露的情况。
类似这样的问题,不难,建议你去看一下他们的C#方面的课程,有解决这个问题的方法 参考资料
http://aspnet.ixueku.com
希望对你有帮助哦
托管的代码没有内存泄漏问题。

我要回帖

更多关于 linux 程序内存泄漏 的文章

 

随机推荐