老是看到LOG日志里有些系统回收的东西。明知道是内存问题。但还真不知道怎么下手。唉,无赖啊。网上找资料海里捞针,不容易啊。看到这篇不错。


1. verbosegc

一般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虚拟机内存管理可以做出的改进。
posted @ 2012-02-02 20:24 悟道2012 阅读(476) 评论(0) 编辑
      Android日志系统提供了记录和查看系统调试信息的功能。日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命
令来查看和使用.

使用logcat命令

你可以用 logcat 命令来查看系统日志缓冲区的内容:
[adb] logcat [<option>] ...
[<filter-spec>] ...
请查看Listing of logcat Command Options ,它有对logcat命 令有详细的描述
.

你也可以在你的电脑或运行在模拟器/设备上的远程adb shell端来使用logcat命 令,也可以在你的电脑上查看日志输出。
$ adb
logcat
你也这样使用:
# logcat
过滤日志输出

每一个输出的Android日志信息都有一个标签和它的优先级.
日志的标签是系统部件原始信息的一个简要的标志。(比如:“View”就
是查看系统的标签).
优先级有下列集中,是按照从低到高顺利排列的:
    V — Verbose (lowest priority)
   
D — Debug
    I — Info
    W — Warning
    E — Error
    F —
Fatal
    S — Silent (highest priority, on which nothing is ever
printed)
在运行logcat的时候在前两列的信息中你就可以看到 logcat
的标签列表和优先级别,它是这样标出的:<priority>/<tag>
.

下面是一个logcat输出的例子,它的优先级就似乎I,标签
就是ActivityManage:

I/ActivityManager(  585): Starting activity: Intent {
action=android.intent.action...}

为了让日志输出能体现管理的级别,你还可以用过滤器来控制日志输出,过滤器可以帮助你描述
系统的标签等级.

过滤器语句按照下面的格式描tag:priority ... , tag 表 示是标签,priority
是表示标签的报告的最低等级. 从上面的tag的中可以得到日志的优先级. 你可以在过滤器中次写tag:priority
.

这些说明都只到空白结束。下面有一个列子,例子表示支持所有的日志信息,除了那些标签
为”ActivityManager”和优先级为”Info”以上的和标签为” MyApp”和优先级为” Debug”以上的。
小等级,优先权报告为tag.

adb logcat ActivityManager:I MyApp:D
*:S

上面表达式的最后的元素 *:S ,,是设置所有的标 签为”silent”,所有日志只显示有”View” and “MyApp”的,用
*:S 的另一个用处是
能够确保日志输出的时候是按照过滤器的说明限制的,也让过滤器也作为一项输出到日志中.

下面的过滤语句指显示优先级为warning或更高的日志信息:
adb
logcat *:W

如果你电脑上运行logcat ,相比在远程adbshell端,你还可以 为环境变量ANDROID_LOG_TAGS
:输入一个参数来设置默认的过滤
export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D
*:S"

需要注意的是ANDROID_LOG_TAGS 过滤器如果 通过远程shell运行logcat 或 用adb shell logcat 来
运行模拟器/设备不能输出日志.
控制
日志输出格式


日志信息包括了许多元数据域包括标签和优先级。可以修改日志的输出格式,所以可以显示出特 定的元数据域。可以通过 -v
选项得到格式化输出日志的相关信息.

brief — Display priority/tag and PID of originating
process (the default format).
process — Display PID only.
tag — Display
the priority/tag only.
thread — Display process:thread and priority/tag
only.
raw — Display the raw log message, with no other metadata
fields.
time — Display the date, invocation time, priority/tag, and PID of
the originating process.
long — Display all metadata fields and separate
messages with a blank lines.

当启动了logcat ,你可以通过-v 选 项来指定输出格式:
[adb]
logcat [-v <format>]

下面是用 thread 来产生的日志格式:
adb logcat -v
thread

需要注意的是你只能-v 选项来规定输出格式 option.
查看 可用日志缓冲区

Android日志系统有循环缓冲区,并不是所有的日志系统都有默认循环缓冲区。为了得到 日志信息,你需要通过-b 选项来启动logcat
。如果要使用循环缓冲区,你需要查看剩余的 循环缓冲期:

radio — 查看缓冲区的相关的信息.
events —
查看和事件相关的的缓冲区.
main — 查看主要的日志缓冲区

-b 选项使用方法:
[adb] logcat [-b
<buffer>]

下面的例子表示怎么查看日志缓冲区包含radio 和 telephony信息:
adb logcat -b
radio
查看 stdout
和stderr


在默认状态下,Android系统有stdout 和 stderr (System.out和System.err )
输出到/dev/null , 在运行Dalvik VM的进程中,有一个系统可以备份日志文件。在这种情况下,系统会用stdout 和stderr 和 优先级
I.来记录日志信息

通过这种方法指定输出的路径,停止运行的模拟器/设备,然后通过用setprop 命 令远程输入日志

$ adb
shell stop
$ adb shell setprop log.redirect-stdio true
$ adb shell
start

系统直到你关闭模拟器/设备前设置会一直保留,可以通过添加/data/local.prop 可
以使用模拟器/设备上的默认设置
Logcat命令列表































OptionDescription
-b <buffer>加载一个可使用的日志缓冲区供查看,比如event 和radio . 默认值是main 。具体查看Viewing Alternative Log Buffers.
-c清楚屏幕上的日志.
-d输出日志到屏幕上.
-f <filename>指定输出日志信息的<filename> , 默认是stdout .
-g输出指定的日志缓冲区,输出后退出.
-n <count>设置日志的最大数目<count> ., 默认值是4,需要和 -r 选 项一起使用。
-r <kbytes>每<kbytes> 时 输出日志,默认值为16,需要和-f 选 项一起使用.
-s设置默认的过滤级别为silent.
-v <format>设置日志输入格式,默认的是brief 格 式,要知道更多的支持的格式,参看Controlling Log Output Format
.




posted @ 2012-02-02 17:46 悟道2012 阅读(112) 评论(0) 编辑

  Android Logcat使用起来可以方便的观察调试内容,除了不能正常的显示中文外(Logcat无法显示中文输出bug依然存在) ,基本上的使用方法(巧用Logcat调试程序)。本次要说明的是平时的Log.v Log.d Log.i Log.w Log.e的区别是什么?

  一、Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v("","");

  二、Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择,如图

  

  三、Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息

  四、Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。

posted @ 2012-02-02 17:44 悟道2012 阅读(68) 评论(0) 编辑

在Android程序中可以使用 android.util.Log 类来输出日志信息,该类提供了下列几个静态方法

Log.v(String tag, String msg);
Log.d(String tag, String msg);
Log.i(String tag, String msg);
Log.w(String tag, String msg);
Log.e(String tag, String msg);

分别对应 Verbose, Debug, Info, Warning, Error.

程序运行后并不会在 Eclipse 的控制台内输出任何信息,那么这些在程序中输出的日志跑哪去了呢? 有两种方法可以查看这些日志,最简单的方法是直接使用 Eclipse菜单 -> Windows -> Show View ->Other -> Android -> LogCat 即可;另外还可以通过SDK提供的工具来看,命令是 adb logcat ,该命令执行后会以tail方式实时显示出所有的日志信息。

posted @ 2012-02-02 17:43 悟道2012 阅读(26) 评论(0) 编辑
在Android中使用Intent在两个Activity间传递数据时,只能是基本类型数据,或者是序列化对象。Intent是一种基于消息的进程内和进程间通信模型,当我们需要在我们应用程序内部,多个Activity间进行复杂数据对象共享交互时,使用Intent就显得很不方便。此时,我们就需要一种数据共享的机制来实现。当然,直接使用java语言中的静态变量是可以的,但在Android中有更为优雅的实现方式。

The
more general problem you are encountering is how to save stateacross several
Activities and all parts of your application. A
staticvariable (for instance, a singleton) is a common Java way of
achievingthis. I have found however, that a more elegant way in Android is toassociate your state with the Application context.


--如想在整个应用中使用,在java中一般是使用静态变量,而在android中有个更优雅的方式是使用Application
context。

As you know, each Activity is also a Context, which is
informationabout its execution environment in the broadest sense. Your
applicationalso has a context, and Android guarantees
that it will exist as asingle instance across your application.
--每个Activity 都是Context,其包含了其运行时的一些状态,android保证了其是single instance的。

The way to do this is
to create your own subclass of android.app.Application,and then specify
that class in the application tag in your
manifest.Now Android will automatically create an
instance of that class andmake it available for your entire application. You can access it fromany context using the
Context.getApplicationContext() method (Activityalso provides a method
getApplication() which has the exact sameeffect):
--方法是创建一个属于你自己的android.app.Application的子类,然后在manifest中申明一下这个类,这是android就为此建立一个全局可用的实例,你可以在其他任何地方使用Context.getApplicationContext()方法获取这个实例,进而获取其中的状态(变量)。
  1. class MyApp extends Application {
     

  2.  
  3.   private String myState;
     

  4.  
  5.   public String getState(){
     

  6.     return myState;  
  7.    }  
  8.   public void setState(String s){  
  9.      myState = s;  
  10.    }  
  11. }  
  12.  
  13. class Blah extends Activity {  
  14.  
  15.   @Override 
  16.   public void onCreate(Bundle b){  
  17.      ...  
  18.      MyApp appState = ((MyApp)getApplicationContext());  
  19.      String state = appState.getState();  
  20.      ...  
  21.    }  

对于Application的生命周期,今天测试了一下,Application类型在该APP被install的时候就已经实例化了,并且onCreate也已经被调用了。


如果需要创建类型里面可能需要用到的对象的话,就可以在构造函数里面实现,但是如果需要将该类型bind
Service或者registerReceiver等操作时,需要将这些操作放到onCreate中,否则会抛出异常。其原因主要是这个对象还没有创建完成,此时你用这个对象来bindservice必然会出现意想不到的情况,所以在使用时还需要注意。

posted @ 2012-02-02 16:50 悟道2012 阅读(61) 评论(0) 编辑

在webService里面Session默认是不可用的,必须得开启Session才能使用,如
[WebMethod(EnableSession = true)]
public string Login(string name)
{
    Context.Session["name"] = name;
    return name;
}
需要在当前方法上启用Session  [WebMethod(EnableSession = true)]

 

另外参见

http://www.cnblogs.com/hoojo/archive/2011/03/16/1985699.html
posted @ 2012-02-02 14:08 悟道2012 阅读(48) 评论(0) 编辑

不知道大家是否想试一下用Android模拟器如何访问自己建的Web站点呢? 下面我将讲一下如何实现.

Step 1:我用的Tomcat作为本地服务器,在Webapps这个目录里,把我的名为kankong的Web工程放进来,启动Tomcat服务器.

在浏览器里输入:http://localhost(或者127.0.0.1):8080/kankong/index.html将出现如下界面:

Step 2:启动Android 模拟器:

如果你在Eclipse里已经启动了Android模拟器就跳过此步.我们如何手动启动Android模拟器呢?

首先运行cmd出现我们习惯的黑屏,输入Android list avd(列出所有AVD模拟器)

然后我们选择其中一个启动以Android 1.5为例子:emulator -debug avd_config -avd android 1.5:

出现我们熟悉的画面如下:

Step 3:打开浏览器输入http://localhost:8080/kankong/index.html?

我们的第一想法是输入http://localhost:8080/kankong/index.html,可是这将不会成功,为什么呢?问题是这样的,android模拟器(simulator)把它自己作为了localhost,也就是说,代码中使用localhost或者127.0.0.1来访问,都是访问模拟器自己!这是不行的!

如果你想在模拟器simulator上面访问你的电脑,那么就使用android内置的IP 10.0.2.2 吧,  10.0.2.2 是模拟器设置的特定ip,是你的电脑的别名alias记住,在模拟器上用10.0.2.2访问你的电脑本机.
也就是输入http://10.0.2.2:8080/kankong/index.html将出现如下界面:

OK~这样就大功告成了!

原作者:魏祝林

原文链接:http://blog.csdn.net/Android_Tutor/archive/2009/12/13/4996752.aspx

posted @ 2012-02-02 11:51 悟道2012 阅读(33) 评论(0) 编辑
悟道2012