java内存泄漏定位求助如何定位

如何分析并定位java的内存泄露? - ITeye问答
发现java进程占用了好几百M内存,导致进程响应很慢,想做一个性能优化。各位可否分享点经验?
用jconsle看看吧。看下部分占内存比较多。
呵呵,是生产环境还是开发环境?要是生产环境几百兆有些时候比较正常,看你的并发量了。具体问题具体分析。
几百兆……加内存好了
已解决问题
未解决问题如何定位内存泄漏问题_百度知道
如何定位内存泄漏问题
我有更好的答案
  内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。  这是C和C++程序员的噩梦之一。  1)实质:  内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费;  2)原理:  内存泄露的关键就是记录分配的内存和释放内存的操作,看看能不能匹配。跟踪每一块内存的生命周期;  3)方法:不同开发环境有不同的检测方法,下面以VisualStudio为例介绍。  在VS中使用时,需加上  #define _CRTDBG_MAP_ALLOC  #include &crtdbg.h&  crtdbg.h的作用是将malloc和free函数映射到它们的调试版本_malloc_dbg和_free_dbg,这两个函数将跟踪内存分配和释放(在Debug版本中有效)  _CrtDumpMemoryLeaks();  函数将显示当前内存泄露,也就是说程序运行到此行代码时的内存泄露,所有未销毁的对象都会报出内存泄露,因此要让这个函数尽量放到最后。
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。没有更多推荐了,
不良信息举报
举报内容:
内存泄漏的检测、定位和解决经验总结
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Android内存泄漏的排查与定位部分心得
如题,过了个节,在做的项目经历了挑战,友盟上频繁报OOM。没有捷径,一个字:查。
本文面向的对象是使用过eclipse或者Android Studio
dump过hprof文件并会使用MAT简单分析内存使用情况的Android开发人员,没有使用过MAT的请自行百度基础使用用法,本文讲的是实战中发生了OOM无处下手的情况。
之前也做过内存的分析,当时还在用eclipse,用的工具无非是dump当前内存情况,然后MAT分析。但是仅仅是初学,使用最短GC路径。现在这个方法并没有生效,例子Dump文件截图如下:
Suspects如图:即MAT帮你猜测的内存泄露地点是bitmap,点下图红色圈起来的图标进入使用内存排行榜,可使用shallowHeap排行,看出使用最多的是byte[],是bitmap耗费比较多,还是无法定位到是哪里出的内存泄露,所以还需要进一步查。
其实这个时候需要看的不止是Shallow
Heap的大小,可以查看的还有Objects这一项,看到底存在了多少对象。这个时候可以使用一个技巧,根据内存泄露的特点,重复打开关掉猜测的内存泄露的Activity,这个时候可以在Android
Studio的&Monitors中看到内存会在一次打开关掉过程中积累增加,并没有随着关掉Activity而回收所有的内存,这说明应用是发生了内存泄露。
所以可以做对比,打开一次Activity跟多次打开关掉Activity,dump两次hprof,对比这两个hprof文件的Objects的size,可以猜测在哪儿发生了泄露,本文使用的是多次打开的情况,记得dump之前要Cause
GC。~~但我们今天要说的还在后面。
下面的操作是最简单的能够快速定位内存泄漏和内存泄漏地点的操作,如下图点OQL(外链简介:),这里说两个最常用的语句:
select * from instanceof android.app.Activity
select * from instanceof android.support.v4.app.Fragment
查询当前存在的Activity和Fragment,大发了~~~大家可以看到下图中的内存泄漏Activity
在内存泄漏的条目上右键Path To GC
Root,就显示出了下面的条目,一级一级点下去就能看到你需要的信息,可能是某个static变量持有,可能是某个观察者没有移除,Good
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。如何定位 Node.js 的内存泄漏
如何定位 Node.js 的内存泄漏
Node.js 进程的内存管理,都是有 V8 自动处理的,包括内存分配和释放。那么 V8 什么时候会将内存释放呢?
在 V8 内部,会为程序中的所有变量构建一个图,来表示变量间的关联关系,当变量从根节点无法触达时,就意味着这个变量不会再被使用了,就是可以回收的了。
Node.js 进程的内存管理,都是有 V8 自动处理的,包括内存分配和释放。那么 V8 什么时候会将内存释放呢?
在 V8 内部,会为程序中的所有变量构建一个图,来表示变量间的关联关系,当变量从根节点无法触达时,就意味着这个变量不会再被使用了,就是可以回收的了。
而这个回收是一个过程性的,从快速 GC 到 最后的 Full GC,是需要一段时间的。
另外,Full GC 是有触发阈值的,所以可能会出现内存长期占用在一个高值,也可以算是一种内存泄漏,可以从《一次 Node.js 应用内存暴涨分析》中找到例子。还有一种就是引用不释放,导致无法进入 GC 环节,并且一直产生新的占用,这一般会发生在 Javascript 层面。
所以,定位内存泄漏问题,一般方案就是找那些不被使用又不会被释放的变量,处理了这些变量,问题一般就可以解决了。如果是 Node.js 底层变量不释放,除了提交 issue 等待解决外,只能通过优化启动参数来解决。
如何找出并解决问题
工欲善其事必先利其器,在排查时,我们还是需要一些工具来帮忙的。
这个是今年初出的 Node.js 调试工具,基于 Electron 将 Node.js 和 Chromium 的功能融合在了一起。操作起来比 node-inspector 方便,开放的 Timeline 功能还是比较实用的,虽然不是实时显示。
仅需要 devtool xxx.js,还可以通过 .devtoolrc 来进行参数定制,具体见
heapdump + chrome devTool
这个是比较传统的定位内存泄漏的组合。heapdump 可以直接在代码中调用生成内存快照,然后将快照文件导入到 chrome devTool 进行分析,之后操作其实和前者就差不多了。不过,这个方案和前者有一点区别就是,前者实际还是在浏览器环境中,所以生成的内存快照会有一些 DOM 对象的存在,会有一定的干扰。而这个方案,是直接调用底层 V8 的方法,生成的快照只有 Node.js 环境中的对象。
这个可以在代码里直接使用,实时检测内存动态,当发生内存泄漏的时候,会触发 ‘leak’ 事件,会传递当前的堆状态,配合 heapdump 有奇效。详见 。
一、重现问题
对于垃圾回收,V8 引擎有很复杂的逻辑来决定什么时候进行回收。很多时候,当我们发现 Node.js 进程所使用的内存快速增长的时候,并不能确定是否是内存泄漏导致的,很有可能是程序设计问题,导致内存的不合理利用。只有当垃圾回收触发,未使用内存被释放后,内存增长还在持续,我们才能确定是发生了内存泄漏。
隐藏的内存泄漏问题,大多是有触发条件的,重现问题是需要这些条件的,所以我们在平时写代码的时候,可以将一些重要环节的参数细节打印在 log 中,这样我们在重现问题是就不会摸不着头脑,乱试一气。
有了参数可以用来重现问题,接下来要确定问题。我们要确定,这部分内存是否没有被 GC 正确释放。那么问题来了,我们如何知道程序进行了垃圾回收呢?很显然,等待并不是办法,我们要主动。
在 Node.js 的启动参数中,提供了暴露手动调用 GC 方法的参数,即 --expose-gc。我们用这个参数来启动应用后,就可以在代码中调用 global.gc() 手动触发垃圾回收操作。同时,使用 process.memoryUsage().heapUsed 获取进程运行时所占用的内存。如果 GC 之后,内存依然没有下降,就可以确定是内存泄露了。
二、生成内存快照
既然内存是问题,我们就需要获取程序运行的内存快照来帮助定位问题。但内存快照并不是随便打得,是有一定技巧的。
我们至少要生成三次内存快照,才能更好的定位问题。这三次中又一次要在问题出现前生成,之后可以在问题持续的过程中生成两次或更多。
为什么要这样做呢?理解起来很简单。第一次是为了获取正常情况下的堆栈信息,而在问题出现后,堆栈信息一定会发生变化,有了第一次的信息,我们才好进行后面的比对,过滤一些无用的信息。而后两次的快照,用来比对某一对象的堆栈变化,来确定是否是有问题的对象。下面会详细应用到。
三、定位问题
用 devTool 的可以忽略下面的过程:
打开 Chrome Devtools ,进入到 Profiles 选项卡,点 Load 按钮,加载之前生成的快照。
对于内存快照,有四个视图,Summary,Comparison,Containment,Statistics,这里面常用的是前三个。
在 Summary 视图中,我们可以看到当前快照的全部信息,以及多个快照之间的信息。在列表里显示的都是对象的构造函数名字,可以先忽略被括号包裹的对象,优先观察其他的对象,最后再来看他们。后面的 shallow size 表示的是对象自身的大小,retained size 表示的是对象和它依赖对象的大小,一般是 GC 不可达的。
在 Comparison 视图中,我们可以进行多个快照之间的对比,这个用处比较大,如果我们将前两次快照进行对比,可能比较快速的定位出问题的对象。注意观察 New、Deleted、Delta,如果是内存泄漏的对象,可能是一直在 New,而没有 Deleted。
在 Containment 视图中,我们可以查看整个 GC 路径,当然一般不会用到。因为展开在 Summary 和 Comparison 列举的每一项,都可以看到从 GC roots 到这个对象的路径。通过这些路径,你可以看到这个对象的句柄被什么持有,从而定位问题产生的原因。值的注意的是,其中背景色黄色的,表示这个对象在 Javascript 中还存在引用,所以可能没有被清除。如果是红色的,表示的是这个对象在 Javascript 中不存在引用,但是依然存活在内存中,一般常见于 DOM 对象,它们存放的位置和 Javascript 中对象还是有不同的,在 Node.js 中很少遇见。
更多的操作方法,可以看这个视频
和。还有 Chrome 的文档 (旧) 和(新)。讲的还是很详细的。(请自备梯子)
四、解决问题
一般在 Javascript 中存在引用而导致内存泄漏的情况,是比较好处理的,只需要在使用后及时的将引用释放掉即可。
所存在的那种内存问题,是属于底层机制的问题,如果等不了 bugfix,就只能先通过一些启动参数来优化内存管理。常用的参数:
当我们找到问题,进行修复后,重复上面的步骤,确认问题已经被解决。有时可能一次并不能解决问题,所以耐心还是很重要的。
可以在这里下载使用到的代码, ,进入 memory-leak 文件夹。
我们来举个例子,应用上面的步骤排查问题,使用 leak-memory 的例子,代码还有另外一个例子,可以自己实践。
这里我们为了方便,我们使用了 devTool。
devTool leak-memory.js
然后在打开的界面中进入内存快照界面,生成第一次快照。当控制台有输出后,间隔的生成两次快照,结果如下。
我们切换视图,对比下三次快照间的区别,可以看到 Foo 这个对象一直在创建而没有被删除。
我们展开 Foo,选择下面的一个实例,查看它的 GC path,可以看到它一直被 neverRelease 持有引用(黄色),所以没有被释放,之后就可以进行问题的处理了。
去掉 // neverRelease.splice(index, 1); 前的注释,然后在重复上面的步骤,你会发现内存的变化已经正常了。
在使用 devTool 时,可以查看运行时的 memory timeline,如果图像呈现阶梯式增长,一般就是存在内存泄漏问题了。正常的应用曲线会类似于锯齿,如图:
转载自:http://taobaofed.org/blog//how-to-find-memory-leak/
作者:凌恒
用云栖社区APP,舒服~
【云栖快讯】青年们,一起向代码致敬,来寻找第83行吧,云栖社区邀请大神彭蕾、多隆、毕玄、福贝、点评Review你的代码,参与互动者将选取50位精彩回复赠送“向代码致敬”定制T恤1件,最终成为“多隆奖”的小伙伴还将获得由阿里巴巴提供的“多隆奖”荣誉证书和奖杯。&&
Node.js 性能平台(Node.js Performance Platform)是面向中...
一种高性能、高可靠、可平滑扩容的分布式内存数据库服务。
高速通道(ExpressConnect)是一款便捷高效的网络服务,用于在云上的不同网络环境间...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效...

我要回帖

更多关于 java内存泄漏定位 的文章

 

随机推荐