熊猫儿 发表于 2016-9-24 21:49

内存的分配与回收以下是Android内存回收与再分配的一些情况:
- Dalvik中每个进程的堆都有虚拟内存范围限制。这个范围取决于逻辑堆尺寸的定义,它可以随着APP的需要随之增长(不过最大只会增长到系统为每个app所分配的内存大小)。
- 堆栈的逻辑尺寸并不等同于堆栈所使用的物理内存大小。当系统检查APP的堆时,会计算一个名为Proportional Set Size(PSS)的值,PSS的意思是,与其他进程共享的,需要清理的页面列表。有关更多PSS的相关信息,请阅读指南:Investigating Your RAM Usage。
- Dalvik堆栈对堆栈的逻辑空间并不是连续排布的,这句话的意思是Android并不会对堆空间进行碎片整理。Android只有在已使用的空间到达堆栈的末端时才会整理堆栈的逻辑空间。不过这不意味着堆所使用的物理空间不能被整理。在垃圾收集之后,Dalvik会先扫描堆并找出无用页面,然后使用madvise将这些页面返回到kernel。所以,成对的分配、回收大段的内存可以使大量的内存能够重复使用。然而,回收小段的内存的效率可能会很低,因为小段内存的页面可能正在被使用,还没有被释放。侦测应用内存为了维持一个多任务执行环境,Android为每个APP的堆大小都设置了硬性限制。具体的堆大小都不相同,这取决于RAM的大小。如果APP已经将所分配的堆容量用完,并还要继续申请更多的内存,那么APP会收到一个OutOfMemoryError错误。在一些情况中,你可能需要知道当前的设备中还有多少堆内存可用。比如,检查多大的数据缓存空间在内存中是安全的。你可以通过getMemoryClass()方法进行这样查询。它会返回一个整型数值,这个数值以兆字节为单位,代表了APP堆内存的可用值。这项内容将会在下面进行详细讨论。APP的切换用户在切换APP时并没有使用交换空间,Android将切换到后台的进程放置在一个LRU(最近最少使用)缓存中。这么说吧,用户先开启了一个APP,那么会专门有个进程为它启动,后来用户离开了该APP,但这个APP的进程并没有退出,那么这时系统会将这个APP的进程缓存下来,所以如果用户再次返回了该APP,那么刚刚缓存的进程会被再次利用,以便完成快速切换。如果APP含有一个缓存进程,并且占用了当前系统并不那么需要的内存,那么在用户不再使用它时,它就会影响到系统的整体性能。所以,随着系统的可用内存减少,系统可能会杀死LRU缓存中最近最少使用到的进程。为了使APP尽可能缓存的时间长,下面的章节会介绍何时应当释放引用。有关更多进程在后台如何缓存以及Android是如何决定哪个进程应当被杀死的相关信息,请参见:Processes and Threads。APP应当如何管理内存APP应当在每个开发阶段考虑RAM的限制,包括APP的设计阶段。下面将会列出几种有效的解决方案:在开发时应当采用以下方式来增加内存的使用效率。尽可能少的使用服务

熊猫儿 发表于 2016-9-24 21:50

如果APP需要使用服务在后台做一些工作,绝不要在服务内做不必要的工作。还要注意,在工作完成之后,如果服务停止失败,则要当心服务的泄露。当启动服务时,系统会为该服务持有一个进程。这会使得系统的开销非常高昂,因为服务所使用的内存不能作为它用。这会减少系统保持在LRU缓存中的进程数量,并会使得APP的转换效率低下。当内存非常紧张或者系统不能够保证有足够的进程来维持当前的服务数量时它甚至会引起系统的卡死。对于以上问题最佳的解决方案就是使用IntentService来限制本地服务的数量。当服务不再需要时,留下服务继续运行是APP常见的一种非常糟糕的内存管理错误。所以不要贪图使服务保持长时运行。不及时停止服务不但会增加APP RAM容量不够用的风险,而且还会使用户觉得该APP做的非常的烂,并顺便将其卸载。在UI不可见时释放内存当用户切换到其它APP时,这时你的APP UI会变得不可见,所以应该释放与UI相关的所有资源。及时释放UI资源可以明显的增长系统缓存进程的能力,这会直接影响到用户的体验。为了可以在用户离开UI后还能收到系统通知,应当在Activity内实现onTrimMemory()方法。在该方法内监听TRIM_MEMORY_UI_HIDDEN标志,这个标志代表了UI目前进入隐藏态,应当释放UI所用到的所有资源。这里要注意,TRIM_MEMORY_UI_HIDDEN标志代表的是APP内所有的UI组件对于用户隐藏。这要与onStop()区分开,该方法是在Activity的实例变的不可见时调用,它是在APP内部Activity之间的切换时调用的。所以尽管在onStop()中释放了Activity的资源比如网络连接,注销广播接收器等等,但是一般不要在该方法内释放UI资源。因为这可以使用户在返回该Activity时,UI现场可以迅速恢复。在内存紧张时释放内存在APP生命周期的任何阶段,onTrimMemory()方法会告知当前设备内存很紧张。你应当在收到以下标志时进一步的释放资源:
[*]TRIM_MEMORY_RUNNING_MODERATE APP目前处于运行态,暂时不会被杀死,但是设备目前处于低内存运行态,并且系统正在杀死LRU缓存中的进程。
[*]TRIM_MEMORY_RUNNING_LOW APP目前处于运行态,暂时不会被杀死,但是设备目前处于极低内存运行态,所以你应当释放无用的资源来增进系统的性能。
[*]TRIM_MEMORY_RUNNING_CRITICAL APP还处于运行态,但是系统已经准备将LRU缓存中的大部分进程杀死,所以APP应当立即释放所有不必要的资源。如果系统没有获得足够数量的RAM空间,那么系统会清除LRU中的所有进程,并会杀死一些主机正在进行的服务。
还有,在APP处于缓存状态时,你可能会收到以下标志:
[*]TRIM_MEMORY_BACKGROUND APP处于低内存运行态,APP的进程处于LRU列表的前端。尽管APP所面临被杀死的风险还比较低,但是系统可能已经做好了杀死LRU进程中的准备。APP应当释放那些易于恢复的资源,这样的话,进程会继续保留在缓存列表中,并且会在用户返回到APP时迅速恢复。
[*]TRIM_MEMORY_MODERATE APP处于低内存运行态,APP的进程处于LRU列表的中部。如果系统的内存进一步的降低,那么APP的进程可能就会被杀死。
[*]TRIM_MEMORY_COMPLETE APP处于低内存运行态。如果系统没有足够内存的话,APP的进程首当其冲会被杀死。APP应当释放在恢复APP时一切不重要的事物。
因为onTrimMemory()方法添加于API 14,所以可以使用onLowMemory()来兼容老版本,它大致与TRIM_MEMORY_COMPLETE标志是等价的。Note: 当系统开始杀死LRU中的进程时,尽管它是自下而上工作的,但是系统还是会考虑这么一种情况:哪个进程消耗的内存比较多,所以如果将该进程杀死后,将会获得更多的内存。所以在APP处于LRU缓存时,尽可能的消耗少量的内存,这样一直维持在缓存列表中的机会才大,才可以在切换回APP时迅速恢复状态。

熊猫儿 发表于 2016-9-24 21:51

检查应该使用多少内存就像我们早期提到的,运行Android系统的设备的RAM空间各有不同,所以提供给每个APP的堆空间也是不同的。你可以通过getMemoryClass()方法获得APP的可用空间。如果APP试图向系统申请比该方法返回值大的内存空间的话,那么它会收到一个OutOfMemoryError错误。在一些特别特殊的环境中,你可以申请更大的堆空间,可以通过在清单文件的< application>标签中添加largeHeap=”true”属性的方式来设置。在设置之后,可以通过getLargeMemoryClass()来查询大尺寸的堆栈空间量。然而,申请大堆空间的APP只有正常用途才应该申请,比如大照片编辑类APP。决不要是因为经常出现了OutOfMemory错误才这么去做,你应该做的是解决那个OutOfMemory的问题。只有在你明确知道正常的堆空间不足以支撑APP的运行时才应该这么做。使用额外的内存空间会严重损害整体的用户体验,因为垃圾收集器会在此消耗更长的时间,并且在任务切换或者执行其它并发操作时系统性能会明显减慢。此外,大堆空间的尺寸在所有的设备上并不是相等的。当运行在某些RAM限制的设备上,大堆空间的尺寸可能与常规的堆空间尺寸相等。所以,就算是申请了大堆空间,那么还是应该使用getMemoryClass()来检查一下常规堆空间大小,并尽量将内存的使用量控制在这个范围以下。避免浪费位图的内存当加载一张图片到内存时,最好是将该图片适配到当前屏幕分辨率大小之后再做内存缓存,如果原图本身分辨率很高的话,最好将其缩小到适合屏幕分辨率大小。要注意,随着位图分辨率的增加,所占的相应内存也一并增加。Note: 在Android 2.3.x之前,位图对象无论分辨率是多大都是以相同的大小出现在堆中的,因为位图的实际像素数据被单独的存放在了本地内存中。这使得位图内存分配的调试变得很困难,因为大多数的堆栈分析工具并不能探测到本地内存的分配。然而,自Android 3.0之后,位图的像素数据被分配与APP的Dalvik堆栈中,这样增进了垃圾回收的效率以及调试能力。使用优化过的数据容器我们建议使用Android框架优化过的数据容器,比如SparseArray,SparseBooleanArray,以及LongSparseArray.常规的HashMap其实效率是很低的,因为它需要为每个映射创建单独的实体。另外SparseArray的工作效率更高,因为它可以避免系统对键或值的自动装箱功能。要对内存的消耗有一定的意识要充分了解你所使用的语言以及库的内存开销,并要一直保持有这种意识,包括在APP的设计阶段。经常表面的事物看起来无伤大雅,但实际上它们所消耗的内存是很高的。比如:
[*]Java的枚举类型需要占用静态常量的两倍内存。你应该坚决制止在Android中使用枚举。
[*]Java中的每个类,包含匿名内部类的代码需要占用500个字节。
[*]每个类的实例需要占用12-16个字节的RAM空间。
[*]将每个实例放入HashMap需要格外花费32个字节的空间。
虽然以上的内容只是会消耗几个字节的空间,但是它们会在程序的内部迅速的积累增加,成为一个巨无霸级的开销。它会使你在分析内存问题的时候让你处于一个非常尴尬的境地,因为这些众多的小对象消耗了大量的内存。当心抽象代码经常开发者会使用抽象代码实现一种良好的程序设计结构,因为抽象代码可以增进代码的灵活性与可维护性。不过,抽象代码会有不菲的开销:通常它们需要更多的执行代码,需要花费更多的时间以及更多的RAM空间来将这些抽象代码映射到内存。所以,如果不是必须的话,最好远离它们。为序列化数据使用纳米级缓冲协议Protocol buffers是一种由Google设计的序列化结构的数据。它与语言无关、与平台无关的、可扩展。与XML类似,但是体积更小,速度更快、也更简单。如果你决定要使用该纳米级缓冲协议,那么就应当在客户端代码中一直使用它。常规的protobufs会生成非常冗长的代码,这会引出相当多的问题:增加内存的消耗,增长APK的体积,减缓执行效率并会迅速接近DEX标志的限制。

熊猫儿 发表于 2016-9-25 21:33

避免依赖注解框架使用Guice、RoboGuice这类注解依赖框架是相当方便的,因为这些框架可以简化代码的书写,以及提供了相应的测试环境。然而,这些框架在扫描代码的注解时会执行大量的初始化工作,这会使得大量的代码映射到RAM中,尽管你不需要降这些代码载入内存。这些被映射的页面会一直驻留在内存中,虽然系统可以将它们清除,但是只有在这些页面长时间驻留在内存中才会执行清理。使用第三方库要当心第三方代码通常不是专门为移动设备而写。当这些代码运行在移动客户端时往往执行效率很低。在决定使用第三方库之前,应该假设正在执行一项很重要的移植工作,并将要负担为移动设备的维护、优化工作。在决定使用之前要分析该库的大小以及RAM的占用。就算是某些库是专门为Android所设计的,但是它们还是存在隐患的,因为每个库所做的事不同。举个栗子,一个库可能使用了纳米级的protobufs,而另一个库则使用了毫米级的protobufs。那么现在在APP中使用了两个级别的protobufs。这两种差异可能会发生在日志、解析、图像加载框架、缓存以及其它任何你不期望的事情上。还要当心掉入共享库的陷阱,这种共享库有一个共同的特点就是,你只使用了该库所提供的很小的功能,你并不希望将其它用不到的大量代码也一并放入你的工程内。在最后,如果你不是特别的需要这个第三方库的话,那么最好的方式就是自己实现一个。优化整体性能有关APP整体性能优化的建议都列在了Best Practices for Performance中。这些建议还包括了CPU的性能优化,除此之外还包括了内存的优化,比如减少布局对象的数量。你还应该读一读有关optimizing your UI的文章,文章内包含了布局调试工具以及lint tool中所提示的一些布局优化建议。使用ProGuard筛除无用代码ProGuard工具可以通过移除无用代码以及以一种无意义的名称重命名类名,属性,方法的方式来达到一种精简、优化、模糊的效果。接下来还必须使用zipalign工具对重命名后的代码进行调整。如果不做这一步将会大大增加RAM的使用量,因为类似于资源这些事物不会再由APK映射到内存。作者PS: 这段话摘自于zipalign的介绍,相当于是说Zipalign的原理与优势: Specifically, it causes all uncompressed data within the .apk, such as images or raw files, to be aligned on 4-byte boundaries. This allows all portions to be accessed directly with mmap() even if they contain binary data with alignment restrictions. The benefit is a reduction in the amount of RAM consumed when running the application.分析RAM的使用状况一旦APP达到一个相对稳定的程度,那么接下来就需要分析APP在各个生命周期的RAM使用情况了。有关如何分析APP的RAM使用情况,请参见:Investigating Your RAM Usage。使用多进程如果它适用于你的APP,那么另一项可能帮助你管理APP内存的升级建议就是将组件部署到不同的进程中。使用这项建议必须总是特别的小心,并且大部分APP不应该使用这项技术,如果处理不当的话它会迅速的增加RAM的消耗。这项技术对于那些运行在后台的工作与前台的工作一样重要的APP极为有用,并且可以单独管理这些操作。

熊猫儿 发表于 2016-9-25 21:34

使用多进程最适合的场景就是音乐播放器。如果整个APP运行在单一的进程中,那么Activity UI所执行的大部分内存分配都会和音乐的播放保持相同的时间,甚至是用户切换到了其它APP。那么像这样的APP就应该拥有两个进程:一个进程负责UI,而另一个的工作就是持续不断的运行后台服务。你可以在清单文件中需要执行单独进程的组件里添加android:process属性来实现独立进程。比如,你可以在需要执行单独进程的服务中添加该属性,并声明该进程的名称”background”(你可以命名任何你想命名的名称):<service android:name=".PlaybackService"         android:process=":background" />
[*]1
[*]2
进程的名称应该以冒号’:’开头,以便确保该进程属于你APP的私有进程。在决定创建一个新进程之前,你应该了解一下内存的影响。为了演示每个进程的执行效果,首先要考虑到一个不做任何事情的进程需要占用大约1.4MB的内存空间,下面显示了空态下的内存信息堆:adb shell dumpsys meminfo com.example.android.apis:empty** MEMINFO in pid 10172 **                Pss   PssShared PrivateShared Private    Heap    Heap    Heap            Total   Clean   Dirty   Dirty   Clean   Clean    Size   Alloc    Free             ------------------------------------------------------Native Heap   0       0       0       0       0       0    1864    1800      63Dalvik Heap   764       0    5228   316       0       0    5584    5499      85 Dalvik Other   619       0    3784   448       0       0      Stack    28       0       8      28       0       0    Other dev   4       0      12       0       0       4   .so mmap   287       0    2840   212   972       0    .apk mmap    54       0       0       0   136       0    .dex mmap   250   148       0       0    3704   148   Other mmap   8       0       8       8      20       0      Unknown   403       0   600   380       0       0      TOTAL2417   148   12480    1392    4832   152    7448    7299   148Note: 如何阅读这些信息请参见Investigating Your RAM Usage。这里的关键数据是Private Dirty及Private Clean所指示的内存。它们分别说明了这个进程使用了大概1.4MB左右的非交换页内存,而另外150K RAM则是被映射到内存之后将要执行的代码所占用的空间。了解空进程状态下的内存占用是相当重要的,它会随着工作的开始迅速增长。比如,下面是一个显示了一些文本的Activity的内存占用情况:

熊猫儿 发表于 2016-9-25 21:34

** MEMINFO in pid 10226 **                Pss   PssShared PrivateShared Private    Heap    Heap    Heap            Total   Clean   Dirty   Dirty   Clean   Clean    Size   Alloc    Free             ------------------------------------------------------Native Heap   0       0       0       0       0       0    3000    2951      48Dalvik Heap1074       0    4928   776       0       0    5744    5658      86 Dalvik Other   802       0    3612   664       0       0      Stack    28       0       8      28       0       0       Ashmem   6       0      16       0       0       0    Other dev   108       0      24   104       0       4   .so mmap2166       0    2824    1828    3756       0    .apk mmap    48       0       0       0   632       0    .ttf mmap   3       0       0       0      24       0    .dex mmap   292       4       0       0    5672       4   Other mmap    10       0       8       8      68       0      Unknown   632       0   412   624       0       0      TOTAL5169       4   11832    4032   10152       8    8744    8609   134现在进程使用了刚刚的三倍内存,将近4MB,只是在UI中展示了一段文本而已。这可以推出一个非常重要的结论:如果你将APP的功能放在多个进程中执行,只有一个进程用于响应UI,而另外的进程则应当避免与UI接触,因为这会迅速的增加RAM的消耗。一旦UI被绘制,那么几乎就很难将内存的用量降下来。另外,当运行超过一个进程时,非常重要的一点是,应当使代码尽可能的精简,因为任何不必要的开销都是因为相同的实现被复制到了每个进程中。比如,如果你正在使用枚举(尽管不应该使用枚举),所有进程的RAM都需要创建并且初始化这些复制到每个进程中的常量,其它任何的抽象适配器、常量或者其它占用内存的都会被复制。使用多进程的另外一个担忧就是它们之间的依赖关系。比如,如果APP内含有ContentProvider,并且该ContentProvider运行于显示UI的进程,那么另一个后台进程的代码需要使用这个ContentProvider时,这就需要该UI进程也加载进RAM中。如果你的服务是一个与UI进程相当权重的后台服务,那么该服务就不应该依赖UI进程中的ContentProvider或者服务。

熊猫儿 发表于 2016-9-25 21:35

Android官方开发文档Training系列课程中文版:管理设备的睡眠状态
标签: android文档设备睡眠设备唤醒屏幕常亮
2016-09-02 08:43 492人阅读 评论(0) 收藏 举报

http://static.blog.csdn.net/images/category_icon.jpg 分类:
翻译(103) http://static.blog.csdn.net/images/arrow_triangle%20_down.jpg


目录(?)[+]

原文地址:http://android.xsoftlab.net/training/scheduling/index.html引言当Android设备处于闲置状态时,它的屏幕首先会变暗,接着会关闭屏幕,最后会将CPU关闭。这些举措可以防止设备的电量迅速被耗尽。但是当APP需要的话,还是会有例外情况:
[*]游戏类APP或者视频类APP需要保持屏幕常亮。
[*]有一部分APP或许不需要屏幕保持常亮,但是它们需要CPU继续保持运转,直到它们的任务执行完毕。
这节课主要学习如何在需要的时候保持设备的唤醒状态而又不至于非常耗电。保持设备的唤醒状态为了避免迅速将电量耗光,Android设备会在进入闲置状态后紧接着进入睡眠状态。不过,还是有一些例外情况的:它们需要保持屏幕常亮或者是保持CPU持续运转状态以便完成某些任务。具体采用什么样的方式这取决于APP的需求。不过,有一条规则就是尽量采取最轻量级的方法,尽可能少的消耗系统资源。保持屏幕常亮某些APP比如游戏类APP或者视频类APP需要保持屏幕常亮。要做到这一点只需要在Activity中使用FLAG_KEEP_SCREEN_ON就可以,不过千万不要在服务或者其它组件中使用该标志:public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);}...}
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
[*]7
[*]8
[*]9
这种方法的优势在于:它不要指定特殊权限,系统会将APP之间的状态切换处理好,也不需要担心有关释放无用资源的问题。另一个实现方式就是在布局文件中使用android:keepScreenOn属性:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:keepScreenOn="true">    ...</RelativeLayout>
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
android:keepScreenOn=”true”的作用效果与使用FLAG_KEEP_SCREEN_ON的效果等同。你可以选择最合适的方式。使用标志的优势在于可以动态的清除该标志的状态,以便于屏幕可以转入关闭状态。Note: 除非可以肯定屏幕不再需要保持常亮,否则不需要我们自己专门去清除该标志。WindowManager会严格把关这些事情:APP转入后台时,APP转入前台时。但是如果你明确要清除该标志以便屏幕可以转入关闭状态,那么可以使用clearFlags():getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)


熊猫儿 发表于 2016-9-25 21:37

保持CPU的运行如果APP希望在系统转入睡眠状态之前完成一些事情,那么可以使用PowerManager系统服务中的WakeLock特性。WakeLock可以使APP控制设备的电源状态。因为持有WakeLock对象可以直接与电源交互,所以只能在必要的时候使用WakeLock。绝不要在Activity中使用WakeLock。就像上面说的那样,如果希望保持屏幕常亮,只需要使用FLAG_KEEP_SCREEN_ON就可以。使用WakeLock的合理场景就是后台服务。再强调一次,使用时应当以最小限度使用该标志,因为它会直接影响到电池的电量。如果要使用WakeLock,首先需要在清单文件中添加WakeLock的权限:<uses-permission android:name="android.permission.WAKE_LOCK" />
[*]1
如果APP还包括了一个与服务做相关工作的广播接收器,那么可以通过WakefulBroadcastReceiver来管理WakeLock。这是一种非常理想的方案。如果APP没有那样的情况,那么也可以使用下面的方法:PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);Wakelock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,      "MyWakelockTag");wakeLock.acquire();
[*]1
[*]2
[*]3
[*]4
如果要释放WakeLock,调用wakelock.release()就好。它会释放你所持有的CPU资源。在任务完成后做这项工作是很重要的,因为这可以防止电池电量被迅速耗光。使用WakefulBroadcastReceiver广播接收器与服务的结合使用非常易于管理后台任务的生命周期。WakefulBroadcastReceiver是一种特殊的广播接收器:它可以创建并管理APP的PARTIAL_WAKE_LOCK。在设备即将转入睡眠状态时,WakefulBroadcastReceiver会将该信号发给服务(通常是IntentService)。如果在收到广播后没有持有WakeLock,那么可以在工作完成之前设备就会转入睡眠状态。这就会导致任务不能及时完成,这并不是我们想看到的。WakefulBroadcastReceiver用法的第一步就是将其添加到清单文件中,与其它广播接收器的添加方式一样:<receiver android:name=".MyWakefulReceiver"></receiver>
[*]1
第二步就是使用startWakefulService()方法来启动MyIntentService。这个方法除了在启动时WakefulBroadcastReceiver持有了一个WakeLock外,其它的都与startService()很相似。在startWakefulService()中所使用的Intent被隐式的携带了一个WakeLock。public class MyWakefulReceiver extends WakefulBroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {      // Start the service, keeping the device awake while the service is      // launching. This is the Intent to deliver to the service.      Intent service = new Intent(context, MyIntentService.class);      startWakefulService(context, service);    }}

熊猫儿 发表于 2016-9-26 10:05

服务结束时,要使用MyWakefulReceiver.completeWakefulIntent()将WakeLock释放。completeWakefulIntent()方法使用了被WakefulBroadcastReceiver传递过来的Intent对象:public class MyIntentService extends IntentService {    public static final int NOTIFICATION_ID = 1;    private NotificationManager mNotificationManager;    NotificationCompat.Builder builder;    public MyIntentService() {      super("MyIntentService");    }    @Override    protected void onHandleIntent(Intent intent) {      Bundle extras = intent.getExtras();      // Do the work that requires your app to keep the CPU running.      // ...      // Release the wake lock provided by the WakefulBroadcastReceiver.      MyWakefulReceiver.completeWakefulIntent(intent);    }}

熊猫儿 发表于 2016-9-26 10:06

数据库的方向 - 行vs列(转自: IBM i 中国开发团队)
标签: 数据库中国ibm
2016-09-01 12:18 96人阅读 评论(0) 收藏 举报

http://static.blog.csdn.net/images/category_icon.jpg 分类:
其它(13) http://static.blog.csdn.net/images/arrow_triangle%20_down.jpg

转载地址:https://www.ibm.com/developerworks/community/blogs/IBMi/entry/database?lang=en原文链接:http://ibmsystemsmag.blogs.com/you_and_i/db2/数据库的方向 - 行vs列如果你是一位数据库专家的话,这篇博客可能帮不了你什么。如果你是一位IT人士,但对数据库技术只知其然的话,这篇博客会很适合你。如果你是非IT人士,又或者你是我的家人,谢谢你们的阅读,但是显然你应该去寻求更适合你的阅读材料。如此,可能会对此话题感兴趣的朋友已经减少了。看来你应该是这样一个人,你是非数据库领域的IT专家,但是你深知数据库的重要性,你可能非常想更多的了解一些当前IT界正在热烈讨论的数据库热门话题。我可以很坦率的告诉大家,虽然我在IBM i的很多个部门工作过,但是我并不是一个DB2的开发人员。所以我会定期的去DB2团队寻求一些聪明的数据库专家给我一些比较高级的数据库指导。尤其,我非常想知道,为什么近来如此多行业都在谈论“列式存储”数据库的原因。所以,我找到了Mark Anderson。 众所周知,Mark是一位杰出的工程师,现在是DB2 for i的首席架构师。下面,我将分享一下我学到的知识。今天的主题也如同很多有关数据库讨论一样主要集中于性能方面。即,新兴的列式数据库和传统的行式数据库在性能方面的比较。顾名思义,这两种数据库架构在存贮数据时的方式是大相径庭的。在行式数据库中,每一行中的每一块数据都是紧挨着另一块数据存放在硬盘中。一般情况下,你可以认为每一行存贮的内容就是硬盘中的一组连续的字节。如果你记得DB 101(你已经学习了数据库的介绍课程,对吧?)中介绍的数据库中每一行都是用来记录一些实体信息的。为了方便我们的讨论,我们假设每一行都包含一个用户的信息,每个用户的所有属性都整块儿存储在硬盘上。如下图所示,虚拟表(或者数组)中的列用来存储每个属性。https://www.ibm.com/developerworks/community/blogs/IBMi/resource/BLOGS_UPLOADED_IMAGES/picc1.png


页: 26 27 28 29 30 31 32 33 34 35 [36] 37 38 39 40 41 42 43 44 45
查看完整版本: 【Android的一些重要知识6。。。。】