一般Java虚拟机要求支持verbosegc选项,输出详细的垃圾收集调试信息。dalvik虚拟机很安静的接受verbosegc选项,然后什么都不做。dalvik虚拟机使用自己的一套LOG机制来输出调试信息。 
如果在Linux下运行adb logcat命令,可以看到如下的输出: 
D/dalvikvm(  745): GC_CONCURRENT 
freed 199K, 53% free 3023K/6343K,external 0K/0K, paused 2ms+2ms 
 
其中D/dalvikvm表示由dalvikvm输出的调试信息,括号后的数字代表dalvikvm所在进程的pid。 
GC_CONCURRENT表示触发垃圾收集的原因,有以下几种:
GC_MALLOC, 内存分配失败时触发
GC_CONCURRENT,当分配的对象大小超过384K时触发
GC_EXPLICIT,对垃圾收集的显式调用(System.gc)
GC_EXTERNAL_ALLOC,外部内存分配失败时触发
freed 199K表示本次垃圾收集释放了199K的内存, 
53% free 3023K/6343K,其中6343K表示当前内存总量,3023K表示可用内存,53%表示可用内存占总内存的比例。 
external 0K/0K,表示可用外部内存/外部内存总量 
paused 2ms+2ms,第一个时间值表示markrootset的时间,第二个时间值表示第二次mark的时间。如果触发原因不是GC_CONCURRENT,这一行为单个时间值,表示垃圾收集的耗时时间。 
 
2. 分析 
(1)虽然dalvikvm提供了一些调试信息,但是还缺乏一些关键信息,比如说mark和sweep的时间, 分配内存失败时是因为分配多大的内存失败,还有对于SoftReference,WeakReference和PhantomReference的处理,每次垃圾收集处理了多少个这些引用等。 
(2)目前dalvik所有线程共享一个内存堆,这样在分配内存时必须在线程之间互斥,可以考虑为每个内存分配一个线程局部存储堆,一些小的内存分配可以直接从该堆中分配而无须互斥锁。 
(3)dalvik虚拟机中引入了concurrentmark,但是对于多核CPU,可以实现parrelmark,即可以使用多个线程同时运行mark阶段。这些都是目前dalvik虚拟机内存管理可以做出的改进。

GC_FOR_MALLOC means that the GC was triggered because there wasn't enough memory left on the heap to perform an allocation. Might be triggered when new objects are being created.

GC_EXPLICIT means that the garbage collector has been explicitly asked to collect, instead of being triggered by high water marks in the heap. Happens all over the place, but most likely when a thread is being killed or when a binder communication is taken down.

There are a few others as well:

GC_CONCURRENT Triggered when the heap has reached a certain amount of objects to collect.

GC_EXTERNAL_ALLOC means that the the VM is trying to reduce the amount of memory used for collectable objects, to make room for more non-collectable.

typedefenum{ 
    GC_FOR_MALLOC, 
    GC_CONCURRENT, 
    GC_EXPLICIT, 
    GC_EXTERNAL_ALLOC, 
    GC_HPROF_DUMP_HEAP 
   }GcReason;

GC_EXTERNAL_ALLOC freed 297K, 49% free 3411K/6663K, external 24870K/26260K, paused 83ms

前面Free的内存是VM中java使用的内存,external是指VM中通过JNI中Native的类中的malloc分配出的内存,例如Bitmap和一些Cursor都是这么分配的。
在Davilk中,给一个程序分配的内存根据机型厂商的不同,而不同,现在的大部分的是32M了,而在VM内部会把这些内存分成java使用的内存和 Native使用的内存,它们之间是不能共享的,就是说当你的Native内存用完了,现在Java又有空闲的内存,这时Native会重新像VM申请,而不是直接使用java的。
例如上边的例子
free 3411K/6663K和external 24870K/26260K
如果这时需要创建一个2M的Bitmap,Native现有内存26260-24870=1390K<2048k,因此他就会向Vm申请内存,虽然java空闲的内存是
6663-3411=3252>2048,但这部分内存Native是不能使用。
但是你现在去申请2M的Native内存,VM会告诉你无法分配的,因为现在已使用的内存已经接近峰值了32M(26260+6663=32923 ),所以现在就会成force close 报OOM。所以现在我们要检查我们的native内存的使用情况来避免OOM。

文章转载自:http://blog.sina.com.cn/s/blog_6610da390101bhqj.html

内存调试的东西D/dalvikvm( 809 ): GC_CONCURRENT freed的更多相关文章

  1. ANDROID开发之GC_CONCURRENT freed

    <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause ...

  2. GC_CONCURRENT freed 循环不停打印日志

    打印类似如下语句: 03-07 19:21:49.562: D/dalvikvm(1677): GC_CONCURRENT freed 2859K, 20% free 12020K/15011K, p ...

  3. 珍惜每一滴水(kbmmw 中的内存调试)

    作为一个服务器端的应用,最基本的要求就是稳定,当然要做一个稳定的服务器端,需要涉及到很多方面, 内存泄露就是稳定的一个致命杀手,因为服务器的物理内存是有限的,即使一个功能有很小的内存泄露,经过 长时间 ...

  4. C语言内存调试技巧—C语言最大难点揭秘

    本文将带您了解一些良好的和内存相关的编码实践,以将内存错误保持在控制范围内.内存错误是 C 和 C++ 编程的祸根:它们很普遍,认识其严重性已有二十多年,但始终没有彻底解决,它们可能严重影响应用程序, ...

  5. C++:互斥量C++实现,内存调试,自动锁

    /*互斥量C++实现+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ class CMutex { public: C ...

  6. Windbg .net内存调试有用的命令(笔记 )

    和.net内存调试相关的Windbg命令 首先.load sosex.dll加载ex调试扩展dll 1.!gcgen [obj地址] 显示对象属于gc代数 2.!dumpgen [0/1/2] dum ...

  7. c/c++内存调试

    Leaktracer,Valgrind,ElectricFence 内存泄漏分类 以发生的方式来分类,内存泄漏可以分为4类: 常发性 发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存 ...

  8. Android——内存调试

    因调试某个重大问题,怀疑到了内存,专门写了个測试脚本.记录一下. 撰写不易,转载请注明出处:http://blog.csdn.net/jscese/article/details/37928823 一 ...

  9. 【python】内存调试

    全文拷贝自:http://blog.csdn.net/BaishanCloud/article/details/76422782 问题定位过程解读 gdb-python:搞清楚python程序在做什么 ...

随机推荐

  1. 【Android】混淆器(ProGuard)

    混淆器(ProGuard) 混淆器通过删除从未用过的代码和使用晦涩名字重命名类.字段和方法,对代码进行压缩,优化和混淆.结果是一个比较小的.apk文件,该文件比较难进行逆向工程.因此,当你的应用程序对 ...

  2. JavaScript的for循环编写九九乘法表

    for(var i = 1; i <= 10; i++) { for(var j = 1; j <= i; j++) { document.writeln(i + '*' + j + '= ...

  3. shell命令从目录中循环匹配关键词

    #!/bin/bash while read line do for file in /home/local/test/* do if test -f $file then sed -n " ...

  4. aehyok.com的成长之路一——开篇

    前言   不得不说最近三个月都没更新博客了,除了6月初的一篇博客外,今天的这一篇算是这三个月里发表的第二篇博客了.不过本人几乎每天都在博客园里刷来刷去,看大家发表的博文,从中汲取营养.确实博客园也可以 ...

  5. WHY数学图形可视化工具(开源)

    WHY数学图形可视化工具 软件下载地址:http://files.cnblogs.com/WhyEngine/WhyMathGraph.zip 源码下载地址: http://pan.baidu.com ...

  6. TStringList中AddObject使用

    结构体定义 PYpType=^TYpType; TYpType=record    yfcode:string;    ypcode:string;    YpUnitPrice:Currency;  ...

  7. Ubuntu上安装和使用SSH,Xming+PuTTY在Windows下远程Linux主机使用图形界面的程序

    自:http://blog.csdn.net/neofung/article/details/6574002 Ubuntu上安装和使用SSH  网上有很多介绍在Ubuntu下开启SSH服务的文章,但大 ...

  8. 源代码目录结构--AngularJS学习笔记(一)

    最近开始接触AngularJS,确实是一个相当不错的东西,可以把很多东西简化掉.又对于其中的双向绑定等的实现很好奇,加之正在学习Javascript的东西,所以觉得从源代码这块开始深入学习Angula ...

  9. RSA算法 Android JAVA C#互通

    RSA算法属非对称加密算法,在实际使用中,往往客户端使用公钥进行加密传递敏感数据,服务端server使用私钥进行解密,这样防止中间人从网络获取敏感数据的明文. Android端主要代码如下: pack ...

  10. RAID卡

        简单的说,RAID是一种把多块独立的物理硬盘按不同方式组合起来形成一个逻辑硬盘,从而提供比单个硬盘有着更高的性能和提供数据冗余的技术.     RAID卡一般分为硬RAID卡和软RAID卡两种 ...