今天自行研究了下json ,感觉非常好用,经过测试比google的GSON快多了
同时Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。功能非常的强悍!
大家也知道,json 在如今互联网时代应用的非常广,因为大家如此的关注,所以对json的解析性能要求也是非常高的。
一、 准备工作
1、 下载依赖库jar包
Jackson的jar all下载地址:http://jackson.codehaus.org/1.7.6/jackson-all-1.7.6.jar
然后在工程中导入这个jar包即可开始工作
官方示例:http://wiki.fasterxml.com/JacksonInFiveMinutes
因为下面的程序是用junit测试用例运行的,所以还得添加junit的jar包。版本是junit-4.2.8
如果你需要转换xml,那么还需要stax2-api.jar
2、 测试类基本代码如下
打印结果 :
串转换成entity-------------
json2:uid=1000,name=xiao liao,upwd=123,number=12.0,isStudent=true
writeMap2Json -----------
{"2":{"uid":1000,"uname":"xiao liao","upwd":"123","number":12.0,"isstudent":true},"1":{"uid":1000,"uname":"xiao liao","upwd":"123","number":12.0,"isstudent":true}}
readJson2Array------------------
>uid=1,name=www,upwd=456,number=234.0,isStudent=false
>uid=5,name=tom,upwd=123,number=3.44,isStudent=false
writeMap2Json -----------
{"2":{"uid":1000,"uname":"xiao liao","upwd":"123","number":12.0,"isstudent":true},"1":{"uid":1000,"uname":"xiao liao","upwd":"123","number":12.0,"isstudent":true}}
大家逐个自己试试吧 ,上面也是我的测试代码
2.第二阶段代码分析(代码在lib_arm目录下的board.c里面,start_armboot函数)
1)初始化CPU及外围硬件
voidstart_armboot (void)
{
init_fnc_t **init_fnc_ptr;
char *s;
#ifdefined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif
/* Pointer is writable since we allocateda register for it */
gd = (gd_t*)(_armboot_start -CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
/* compiler optimization barrier neededfor GCC >= 3.4 */
__asm__ __volatile__("": ::"memory");
memset ((void*)gd, 0, sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd -sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));
gd->flags |= GD_FLG_RELOC;
monitor_flash_len = _bss_start -_armboot_start;
for (init_fnc_ptr = init_sequence;*init_fnc_ptr; ++init_fnc_ptr) {
if((*init_fnc_ptr)() != 0) {
hang ();
}
}
解释:定义二级指针init_fnc_ptr指向一个存放函数指针的数组,init_fnc_ptr是typedef int (init_fnc_t) (void)类型,即函数类型,init_fnc_ptr可以指向一个没有参数,返回值为int型的函数指针的地址,我们看上面代码最后的for循环init_fnc_ptr = init_sequence,if中会使用(*init_fnc_ptr)()方式调用init_sequence中的函数(函数名可以看为一个地址),如果返回值不是0,则执行hang报错。gd = (gd_t*)(_armboot_start -CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)); 我们知道,malloc区域、stack区域、bdinfo数据、gd_t在内存的位置是放在upper of uboot。__asm__ __volatile__("":: :"memory");这条是内嵌汇编,请查看另一篇介绍内嵌汇编的博文。
gd->bd指针指向数据类型为bd_t的结构体,bd_t结构体记录开发板的参数,例如串口波特率、ip地址、机器类型、启动参数、环境变量位置等。
monitor_flash_len= _bss_start - _armboot_start; bss段是u-boot最后一个段,bss最终需要清零,这时候不再需要搬移,可以参考链接脚本u-boot.lds。
下面分析for循环执行的函数:
#ifdefined(CONFIG_ARCH_CPU_INIT)
arch_cpu_init, /* basic arch cpudependent setup */
#endif
这里我们定义了CONFIG_ARCH_CPU_INIT,所以执行函数arch_cpu_init。跳到这里,又有一个宏,CONFIG_ARCH_CPU_INIT,这个宏也是定义了的,所以可以继续看,
board_init:
30,31行一个是记录机器类型,一个是指定向内核传参的地址。
继续分析,宏CONFIG_USE_IRQ),函数interrupt_init不执行
init_baudrate:
139行使用getenv_r函数在default_environment里找baudrate关键字,找到后把“=”号后面的值赋值给gd->baudrate,然后
再放到gd->bd->bi_baudrate里面。simple_strtoul是uboot实现的字符串转UL类型。
serial_init:什么都没做,保持默认的8位数据、无奇偶校验、1 停止位、无开始位。
console_init_f:gd->have_console = 1就这一句话
display_banner:串口打印uboot信息,就是uboot启动的时候我们看到的信息,这里使用的是printf,但是我们追进去后,关注的函数
应该是serial_putc,它是真实向串口输出一个字符的函数,这个函数会递归调用,应该说自己调用自己,遇到\n结束。
print_cpuinfo:打印CPU信息,CPU型号和速度 CPU:...
checkboard:打印开发板信息 BOARD:...
dram_init:
记录dram的起始地址,0x30000000,size为256M(smdkc100的)
display_dram_config:因为没有定义DEBUG,所以打印DRAM:256M
2)配置malloc空间
这个函数的作用是记录堆栈空间的起始地址、结束地址、当前地址。
4)环境变量初始化
5)网络初始化
6)设备列表初始化
7)配置功能函数表
8)终端完全初始化
9)开中断异常向量表
10)网卡芯片初始化
11)一些后续初始化
12)main_loop详解
等有时间,会针对这些问题在新的文章中深入浅出说明上述问题
关于进程的内存占用情况查询,大家可以参考国外论坛的一个帖子(http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-android),这个帖子在国内被转载颇多,很有参考价值,因为其中对"Pss", "PrivateDirty"和 "SharedDirty"的概念做了一定阐述,使大家看到这几个参数时不会云里雾里。
后面跟帖中也有打印进程内存使用情况的代码,还附有跟帖人对那段代码的疑问,代码如下。代码中打印信息的循环看似多余,明显,由于输入数组pids[]只有一个元素,返回的memoryInfoArray[]数组也只会含有一个元素,那段循环的意义就只有增强代码的可扩展性了。
ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE); MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); Log.i(TAG, " memoryInfo.availMem " + memoryInfo.availMem + "\n" ); Log.i(TAG, " memoryInfo.lowMemory " + memoryInfo.lowMemory + "\n" ); Log.i(TAG, " memoryInfo.threshold " + memoryInfo.threshold + "\n" ); List<RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses(); Map<Integer, String> pidMap = new TreeMap<Integer, String>(); for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) { pidMap.put(runningAppProcessInfo.pid, runningAppProcessInfo.processName); } Collection<Integer> keys = pidMap.keySet(); for(int key : keys) { int pids[] = new int[1]; pids[0] = key; android.os.Debug.MemoryInfo[] memoryInfoArray = activityManager.getProcessMemoryInfo(pids); for(android.os.Debug.MemoryInfo pidMemoryInfo: memoryInfoArray) { Log.i(TAG, String.format("** MEMINFO in pid %d [%s] **\n",pids[0],pidMap.get(pids[0]))); Log.i(TAG, " pidMemoryInfo.getTotalPrivateDirty(): " + pidMemoryInfo.getTotalPrivateDirty() + "\n"); Log.i(TAG, " pidMemoryInfo.getTotalPss(): " + pidMemoryInfo.getTotalPss() + "\n"); Log.i(TAG, " pidMemoryInfo.getTotalSharedDirty(): " + pidMemoryInfo.getTotalSharedDirty() + "\n"); } }在看到上述代码之前,自己按照API说明也写了类似代码如下,包含了更多的输出参数。如果要检查其他进程的内存使用情况,可略去循环中的条件判断。按stackoverflow.com中帖子的说法 Pss的值是最能表明进程使用内存状况
public long getmem_SELF() { ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> procInfo = am.getRunningAppProcesses(); for (RunningAppProcessInfo runningAppProcessInfo : procInfo) { System.out.println(runningAppProcessInfo.processName+ String.format(",pid = %d", runningAppProcessInfo.pid)); if( runningAppProcessInfo.processName.indexOf(this.getPackageName()) != -1 ) { int pids[] = {runningAppProcessInfo.pid}; Debug.MemoryInfo self_mi[] = am.getProcessMemoryInfo(pids); StringBuffer strbuf = new StringBuffer(); strbuf.append(" proccess Name:").append(runningAppProcessInfo.processName) .append("\n pid:").append(runningAppProcessInfo.pid) .append("\n dalvikPrivateDirty:").append(self_mi[0].dalvikPrivateDirty) .append("\n dalvikPss:").append(self_mi[0].dalvikPss) .append("\n dalvikSharedDirty:").append(self_mi[0].dalvikSharedDirty) .append("\n nativePrivateDirty:").append(self_mi[0].nativePrivateDirty) .append("\n nativePss:").append(self_mi[0].nativePss) .append("\n nativeSharedDirty:").append(self_mi[0].nativeSharedDirty) .append("\n otherPrivateDirty:").append(self_mi[0].otherPrivateDirty) .append("\n otherPss:").append(self_mi[0].otherPss) .append("\n otherSharedDirty:").append(self_mi[0].otherSharedDirty) .append("\n TotalPrivateDirty:").append(self_mi[0].getTotalPrivateDirty()) .append("\n TotalPss:").append(self_mi[0].getTotalPss()) .append("\n TotalSharedDirty:").append(self_mi[0].getTotalSharedDirty()); Log.v("TEST",strbuf.toString()); } } return 0; }
翻译:"Pss", "PrivateDirty"和 "SharedDirty"有什么区别
Android(亦即Linux)中,大量内存实际由多个进程共享,所以一个进程实际占用多少内存并不明确。甚至不太清楚哪些分页被添加到磁盘。
这样,要是你要获取所有实际映射在每个进程的物理内存值,然后试图加总求和,你可能会得到一个远大于实际内存总量的值。
Pss是考虑共享内存的内核计算尺度 -- 基本上一个进程的每个内存页面被按一个比率缩减,这个比率和同样使用该页面的其他进程的数量有关。理论上你可以累计所有进程的Pss占用量来检查所有进程的内存占用量,也可以比较进程的Pss来大致发现进程各自的权重。
另一个有趣的参数是PrivateDirty,它基本上是进程内不能被分页到磁盘的内存,也不和其他进程共享。查看进程的内存用量的另一个途径,就是当进程结束时刻,系统可用内存的变化情况(也可能会很快并入高速缓冲或其他使用该内存区的进程,[微笑这样一来,企图就落空了:-)])。
原文
But as to what the difference is between "Pss", "PrivateDirty", and "SharedDirty"... well now the fun begins.
A lot of memory in Android (and Linux systems in general) is actually shared across multiple processes. So how much memory a processes uses is really not clear. Add on top of that paging out to disk (let alone swap which we don't use on Android) and it is even
less clear.
Thus if you were to take all of the physical RAM actually mapped in to each process, and add up all of the processes, you would probably end up with a number much greater than the actual total RAM.
The Pss number is a metric the kernel computes that takes into account memory sharing -- basically each page of RAM in a process is scaled by a ratio of the number of other processes also using that page. This way you can (in theory) add up the pss across all
processes to see the total RAM they are using, and compare pss between processes to get a rough idea of their relative weight.
The other interesting metric here is PrivateDirty, which is basically the amount of RAM inside the process that can not be paged to disk (it is not backed by the same data on disk), and is not shared with any other processes. Another way to look at this is
the RAM that will become available to the system when that process goes away (and probably quickly subsumed into caches and other uses of it).