garbage collection

|

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.

-----------------------
안드로이드용 JVM인 Dalvik VM에는 여러가지 실행 옵션이 있습니다. dalvikvm -help 명령으로 가능한 옵션들을 볼 수 있습니다.

$ adb shell
# dalvikvm -help
dalvikvm -help

dalvikvm: [options] class [argument ...]
dalvikvm: [options] -jar file.jar [argument ...]

The following standard options are recognized:
  -classpath classpath
  -Dproperty=value
  -verbose:tag  ('gc', 'jni', or 'class')
  -ea[:<package name>... |:<class name>]
  -da[:<package name>... |:<class name>]
   (-enableassertions, -disableassertions)
  -esa
  -dsa
   (-enablesystemassertions, -disablesystemassertions)
  -showversion
  -help

The following extended options are recognized:
  -Xrunjdwp:<options>
  -Xbootclasspath:bootclasspath
  -Xcheck:tag  (e.g. 'jni')
  -XmsN  (min heap, must be multiple of 1K, >= 1MB)
  -XmxN  (max heap, must be multiple of 1K, >= 2MB)
  -XssN  (stack size, >= 1KB, <= 256KB)
  -Xverify:{none,remote,all}
  -Xrs
  -Xint  (extended to accept ':portable' and ':fast')

These are unique to Dalvik:
  -Xzygote
  -Xdexopt:{none,verified,all}
  -Xnoquithandler
  -Xjnigreflimit:N  (must be multiple of 100, >= 200)
  -Xjniopts:{warnonly,forcecopy}
  -Xdeadlockpredict:{off,warn,err,abort}
  -Xstacktracefile:<filename>
  -Xgc:[no]precise
  -Xgenregmap
  -Xcheckdexsum

Configured with: debugger profiler hprof show_exception=1

Dalvik VM init failed (check log file)

안드로이드 환경에서 우리는 dalvikvm 명령어를 실행하여 직접 애플리케이션 프로세스를 띄우지는 않습니다. 때문에 달빅 VM에 직접적으로 옵션을 전달할 수가 없습니다. 
그대신 안드로이드는 시스템 프로퍼티(system properties)를 설정하여 달빅 VM 실행옵션을 바꾸는 방법을 제공합니다. 간단하게는 setprop 명령어로 실행옵션을 바꿀 수 있습니다.
adb shell setprop dalvik.vm.[옵션명] [옵션값]

위와 같은 형식으로 달빅VM 관련 프로퍼티를 설정한 후, zygote 프로세스를 재시작하면(adb shell stop;adb shell start) 새로 런치되는 앱 프로세스에 변경사항이 적용됩니다.

VM 옵션에 대응하는 dalvik.vm.* 형식의 프로퍼티명이 정확히 무엇인지는 framework/base/core/jin/AndroidRuntime.cpp 소스를 참조하면 알 수 있습니다. 일단 제가 찾아낸 프로퍼티명과 프로퍼티값 샘플은 다음과 같습니다.

# -Xmx
dalvik.vm.heapsize

# -Xstacktracefile (기본값 /data/anr/traces.txt)
dalvik.vm.stack-trace-file 

# -Xcheck:jni (값은 true or false)
dalvik.vm.checkjni 

# -Xjniopts
dalvik.vm.jniopts

# -ea (값은 all, ?, ...)
dalvik.vm.enableassertions

# v=a,o=v와 같은 형식으로 값 설정
# v=a는 -Xverify:all, v=n은 -Xverify:none, v=r은 -Xverify:remote에 해당
# o=a는 -Xdexopt:all, o=v는 -Xdexopt:verified, o=n은 -Xdexopt:none에 해당
# m=y는 -Xgenregmap -Xgc:precise에 해당
dalvik.vm.dexopt-flags

# -Xint (값은 int:portable or int:fast or int:jit)
dalvik.vm.execution-mode 

# -Xdeadlockpredict
dalvik.vm.deadlock-predict

# -Xcheckdexsum (값은 true or false)
dalvik.vm.check-dex-sum 

# -Xthreshold
dalvik.vm.jit.threshold

# -Xjitop
dalvik.vm.jit.op

# -Xincludeselectedop
dalvik.vm.jit.includeop

# -Xjitmethod
dalvik.vm.jit.method 

# -Xincludeselectedmethod
dalvik.vm.jit.includemethod 

# -Xjitprofile
dalvik.vm.jit.profile  

-----------------
http://embenux.blogspot.com/2010/11/dalvik-heap-data-structure.html#!/2010/11/dalvik-heap-data-structure.html

Android Application에서 ‘new’ 를 이용해서 Object를 생성할 경우 이를 위한 Heap allocation이 일어나는 과정을 설명한다. 할당에 실패할 경우를 함께 살펴봄으로써 Out-Of-Memory Exception이 발생하는 과정 또한 알아보도록 하자.

dalvik/vm/mterp/armv5te/OP_NEW_INSTANCE.S

새로운 Java Object/Class를 생성할 경우 interpreter에 의해서 호출되는 ARMv5te용 어셈블리 루틴이다. Class를 초기화 한 이후에 dvmMalloc의 인자로 들어갈 ALLOC_DONT_TRACK flag를 설정하여 아래의 dvmAllocObject를 호출하게 된다. 여기서 말하는 ALLOC_DONT_TRACK flag는 메모리 할당 루틴에서 내부적으로 관리하는 리스트에 굳이 추가하지 않아도 된다는 것을 의미하며 GC 대상에서 제외함을 의미하는 것은 아니다.

   cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
   bne     .L${opcode}_needinit        @ no, init class now
.L${opcode}_initialized: @ r0=class
   mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
   bl      dvmAllocObject              @ r0<- new object
  • dvmMalloc의 flag
    • ALLOC_DEFAULT
    • ALLOC_NO_GC
    • ALLOC_DONT_TRACK
    • ALLOC_FINALIZABLE

Object* dvmAllocObject(ClassObject* clazz, int flags)

이번 Allocation에 대한 설명은 Class Object를 생성하는 경우이므로 이에 대한 몇 가지 특별한 처리가 필요하다.
우선 Class가 초기화 되었거나 초기화 중 인지를 검사하는 등의 몇 가지 Sanity Check를 수행한다. 그 후에는 ALLOC_FINALIABLE flag를 추가로 설정하여 다음에 설명할 dvmMalloc을 호출한다. 여기서 설정된 flag는 추후 GC가 수행될 때 반드시 finalize() method가 호출되어야 함을 명시하는 것이다.

할당에 성공했을 경우 Class Object의 메모리 할당을 추적하기 위한 몇 가지 정보를 추가로 기록하게 된다.

newObj = dvmMalloc(clazz->objectSize, flags);

이 함수는 더 이상 Object나 Class 단위의 메모리 할당과는 관련이 없음에 주목하자.  실질적인 메모리 할당이 이뤄지는 과정 만을 놓고 본다면 이 함수에서 호출되는 tryMalloc(size) 함수 (밑에서 설명)를 살펴봐야 하지만 전달 인자 중 flag에 대한 처리는 이 함수 내에서 마무리가 된다.

우선 Object가 ALLOC_FINALIZABLE인 경우 GcHeap구조체에 존재하는 Object 목록에 추가해준다. 여기서 hc->data는 tryMalloc을 통해서 반환 받은 메모리를 가리키는 포인터이다.

       if ((flags & ALLOC_FINALIZABLE) != 0) {
           if (!dvmHeapAddRefToLargeTable(&gcHeap->finalizableRefs,
                                   (Object *)hc->data))

또한 NO_GC가 설정된 경우도 GcHeap의 관련 목록에 추가하게 된다.

      ptr = hc->data;
      if ((flags & ALLOC_NO_GC) != 0) {
           if (!dvmHeapAddToHeapRefTable(&gcHeap->nonCollectableRefs, ptr)) {

마지막으로 내부 관리를 위한 메모리 할당 리스트에 추가한다. 하지만 Class Object의 경우 ALLOC_DONT_TRACK이 켜져 있으므로 실제로는 추가되지 않을 것이다.

       if ((flags & (ALLOC_DONT_TRACK | ALLOC_NO_GC)) == 0) {
           dvmAddTrackedAlloc(ptr, NULL);

지금까지는 tryMalloc이 성공적으로 수행될 경우이며, 만약 실패한다면 가용 메모리가 없음을 의미하므로 OutOfMemory Exception을 던지며 메모리 할당의 모든 과정이 종료된다.

       if (ptr == NULL)
throwOOME();

static DvmHeapChunk *tryMalloc(size_t size)

가정 먼저 하는 일은 요청하는 메모리 크기가 과도하게 큰 경우를 걸러내는 것이다. heapSizeMax는 현재 16MB로 되어 있으며 이 크기가 한번에 할당 가능한 최대 Heap Object의 크기라고 보면 된다. 만약 이 크기를 넘어설 경우 NULL을 반환하여 결국 Out-Of-Memory Exception을 발생시키게 되는데, 그 전에 SoftReference를 모두 회수하는 과정을 수행하고 있다. SoftReference를 수행하는 것은 반드시 수행해야하는 일은 아니지만 Dalvik 개발자는 이 시점이 메모리를 정리할 시기라고 판단한 것으로 보인다.

   if (size >= gDvm.heapSizeMax) {
       LOGW_HEAP("dvmMalloc(%zu/0x%08zx): "
               "someone's allocating a huge buffer\n", size, size);
       hc = NULL;
       goto collect_soft_refs;
   }

이제 본격적으로 메모리 할당에 들어간다. 여기서 원래 요청 크기에 DvmHeapChunk의 크기를 더해서 할당을 요청하는데 이는 DvmHeapChunk내의 Profile 정보를 위한 것이며 별도로 설정하지 않는다면 이 부분은 없는 것이 기본이다.

   hc = dvmHeapSourceAlloc(size + sizeof(DvmHeapChunk));
   if (hc != NULL) {
       return hc;
   }

dvmHeapSourceAlloc의 내부를 잠시 살펴 보면 다음과 같다. 즉, 현재 할당된 크기에 새로 할당할 크기를 더한 값이 softLimit를 넘지 않는다면 mspace_calloc을 이용해서 메모리를 할당한다. mspace 관련 내용은 앞서 설명했으므로 추가 설명은 하지 않기로 한다.

   if (heap->bytesAllocated + n <= hs->softLimit) {
       ptr = mspace_calloc(heap->msp, 1, n);
   }

만약 softLimit를 넘어선다면 어떻게 될까? 이 경우 GC를 수행하고 같은 방법으로 다시 한번 메모리 할당을 시도한다. gcForMalloc의 인자는 Soft Reference에 대해서 GC를 수행할 것인지를 알려주는 것인데 이번 호출에서는 우선 포함하지 않는 것으로 진행하고 지속적으로 메모리 할당에 실패할 경우에만 Soft Reference를 대상으로 GC를 하게 된다.

   gcForMalloc(false);
   hc = dvmHeapSourceAlloc(size + sizeof(DvmHeapChunk));
   if (hc != NULL) {
       return hc;
   }

GC를 수행한 이후에도 또 다시 실패한다면 이제는 진정 Heap 크기를 늘려야 할 상황이다.

  hc = dvmHeapSourceAllocAndGrow(size + sizeof(DvmHeapChunk));

앞서 수행한 dvmHeapSourceAlloc과의 차이는 다음과 같이 Heap의 크기를 늘리고 나서 할당을 다시 시도한다는 것이다.

   max = heap->absoluteMaxSize;
   max -= hs->externalBytesAllocated;
   mspace_set_max_allowed_footprint(heap->msp, max);
   ptr = dvmHeapSourceAlloc(n);

여기까지 수행을 하면 대부분의 경우는 할당에 성공하게 된다. 하지만 이런 노력에도 불구하고 메모리 할당에 실패한다면 Out-Of-Memory Exception을 발생시키기 전에 Soft Reference를 모두 정리하여 메모리 회수에 들어가게 된다. 이는 Java VM 규격에 명시된 바이기도 한다.

   gcForMalloc(true);
   hc = dvmHeapSourceAllocAndGrow(size + sizeof(DvmHeapChunk));
0

Add a comment

  • 이번 장에서는 Dalvik VM Heap을 구성하고 있는 자료 구조와 자료 구조가 생성되는 초기화 과정을 설명한다.

    mspace (Memory Space)

    • bionic/libc/bionic/dlmalloc.c/h
    • typedef void* mspace


    Android에서 Native application의 메모리 할당 및 해제는 ‘libcutils’ library의 일부분인 ‘dlmalloc’ 모듈이 담당한다. ‘dlmalloc’은 Doug Lea가 작고 빠른 메모리 관리자를 표방하여 개발한 것인데 , ‘mspace’는 ‘dlmalloc’에서 부수적으로 제공되는 기능이다. 일반적인 malloc류와의 차이점은 최초 생성된 특정 메모리영역 만을 대상으로 이후의 memory 할당/해제가 수행된다는 것이다. 즉, 메모리 관리에 대해서 더 적극적인 통제를 가할 수 있다는 특징이 있다.

    본질적으로 ‘mspace’는 heap 할당을 위한 순수한 메모리 공간을 의미한다고 볼 수 있다. 인접한 (Contiguous) 공간과 그렇지 않은 공간의 두 가지 옵션이 존재하는데 현재(Froyo 기준)는 인접한 공간을 할당하도록 설정되어 있다. non-contiguos 공간에 대해서는 현재 구현이 되어 있지 않은 상태여서 향후  용도는 분명치 않다. (/system/core/include/cutils/mspace.h: 36, USE_CONTIGUOUS_MSPACE 참조)

    ‘dlmalloc’은 mspace를 다루기 위해 다음과 같은 Method를 지원한다.
    • mspace create_mspace (size_t capacity, int locked);
      • 최초 메모리 생성은 ‘create_mspace’ 호출을 통해서 가능하다. 내부적으로는 ‘/dev/zero’를 열고 mmap system call을 통해 원하는 메모리를 확보한다. 이때 ‘/dev/zero’는 특정 file과 연계되지 않은 anonymous memory를 제공하는 역할을 한다.
    • size_t destroy_mspace (mspace msp);
    • mspace create_mspace_with_base (void*base size_t capacity, int locked);
    • void* mspace_malloc (mspace msp, size_t bytes);
    • void *mspace_free(mspace msp, void* mem);
    • void *mspace_merge_objects(mspace msp, voice* mema, void* memb);
      • 이미 할당된 두 메모리 영역, mema와 memb를 서로 합쳐주는 기능을 담당한다. 두 영역은 서로 인접해야 성공적으로 수행되며 메모리 단편화를 막기 위한 용도이다.
    • size_t mspace_footprint(mspace msp);
      • mspace에서 실제로 할당된 메모리를 byte단위로 반환한다.
    • void mspace_set_max_allowed_footprint(mspace msp, size_t bytes)
      • 할당이 허용되는 최대 사이즈를 설정한다.


    mspace_contig_state & mstate (mspace contiguous state & memory state)
    • mspace_contig_state: system/core/libcutils/mspace.c
    • mstate: bionic/libc/bionic/dlmalloc.c/h


    ‘mspace’는 메모리 공간이면서 할당/해제 요청을 처리하기 위한 정보인 ‘mstate’ (malloc state)를 포함하고 있다. (bionic/libc/bionic/dlmalloc.c: struct malloc_state 참조) 하지만 이 정보는 기존 malloc에서 사용되던 것이므로  ‘mspace’를 다루기 위한 추가적인 자료 구조가 필요한데, 그것이 바로 ‘mspace_contig(uous)_state’라고 볼 수 있다. mmap으로 할당 받은 메모리의 가장 앞 부분에 위치하고 있으며 이를 도식화 하면 다음과 같다.


    또한 ‘mspace_contig_state’ 자료 구조의 구성을 살펴 보면 다음과 같다. 즉, ‘brk’는 현재 사용 가능한 지점을 가리키게 되고 ‘top’은 최초 할당된 메모리 블럭의 가장 끝 단의 주소를 담게 된다.

    또한 ‘mstate’에는 현재 메모리 할당량 및 최대 메모리 할당량을 기록하기 위해서 다음과 같은 멤버 변수를 가지고 있음을 눈여겨 볼 필요가 있다. 이 값들이 어떻게 활용되는지는 추후 자세히 살펴 볼 예정이다.
    • mstate.footprint
    • mstate.max_allowed_footprint


    Heap & HeapSource

    • dalvik/vm/alloc/HeapSource.c
    • dalvik/vm/alloc/Heap.c


    mspace가 메모리 할당/해제를 위한 primitive에 해당한다면 Heap/HeapSource는 mspace를 기반으로 Dalvik VM의 Heap을 표현하고 관리하는 자료 구조라고 정의할 수 있다.

    우선 Heap은 mspace를 멤버 변수로 가져가면서 직접적인 연결 고리 역할을 하고 있다. 그 외에도 다음과 같은 멤버를 가지고 있다.
    • mspace msp
      • Heap 할당에 사용되는 메모리 자원
    • HeapBitmap objectBitmap
      • Heap안의 Object 위치를 추적하기 위한 비트맵
    • size_t absoluteMaxSize
      • Heap이 커질 수 있는 최대 사이즈
    • size_t bytesAllocated
      • 오버헤드를 포함해서 실질적으로 Object를 할당하는데 소모된 모든 메모리 사이즈이며 정확한 값은 아닐 수 있음에 유의해야 한다. 정확한 값을 얻으려면 다소의 오버헤드를 감수하더라도 mspace에서 관리하는 ‘ mspace_usable_size()’를 사용해야 한다.
    • size_t objectsAllocated
      • 현재까지 할당된 Object의 숫자


    Dalvik VM은 process마다 독자적인 Heap을 관리하고 있다. 다시 말해서 Heap관리 관점에서만 보면 process간에 어떠한 교류도 없다는 말이다. 이렇게 볼 때 특정 process안에서의 전체적인 Heap은 HeapSource 자료구조로 대변될 수 있다. 실제로 HeapSource는 최대3개까지의 Heap을 포함하고 있으며 HeapSource자료구조의 변수는 Garbage Collection을 제어하는 핵심적인 정보를 담고 있다.
    • size_t targetUtilization
      • 현재 Heap 크기에서 실제로 할당된 Heap의 비율. 만약 메모리 할당이 지속적으로 요구된다면 순간적으로는 이 비율 이상의 Heap이 할당되겠지만 결국에는 GC를 거치고 Heap 크기가 증가하여 Target을 추종하도록 되어 있다.
      • Default는 0.5, 즉 50% 비율이지만 setTargetHeapUtilization Method를 통해 Java단에서 설정 가능하다. 예를 들어  System Server의 경우는 80%를 가지도록 하고 있는데, 항상 동작하는 모듈이므로 통제 가능한 코드라는 가정 하에 최대한 메모리를 효율적으로 쓰도록 설계되었다고 볼 수 있다. 각 요소 요소에 인위적인 GC가 발생하도록 튜닝을 했다는 점도 주목할 만하다.
    • size_t minimumSize
      • Java단에서 .setMinimumHeapSize 함수를 통해서 설정 가능하며 Launcher2의 경우 4MB로 설정하고 있다.
    • size_t startSize
    • size_t absoluteMaxSize
      • VM startup option인 -Xmx 또는 system property인 dalvik.vm.heapsize를 통해서 설정된 값으로 최대 Heap size의 한계를 의미한다. 보통 process당 돌아가는 Heap의 허용 범위를 줄이거나 늘일 경우 사용하고 있으며 Android Platform Version 및 화면해당도 등에 따라 최적의 값을 설정해야 한다. External Allocation을 포함한 수치라는 것에 유의해야 한다.
    • size_t idealSize
      • 실질적인 메모리 할당의 상한치를 규정한 값으로 Old Heap 뿐 아니라 External Allocation (JNI를 통해서 Native에서 할당해간 메모리)를 포함한다.
    • size_t softLimit
      • idealSize에서 Old Heap 및 External Allocation을 제외한 메모리를 뜻한다. 즉, Active Heap에서 GC를 수행하지 않고 할당 가능한 메모리의 상한 값이다. idealSize가 변경되면 그에 맞춰서 함께 변경이 된다.
    • Heap heaps[HEAP_SOURCE_MAX_HEAP_COUNT]
      • 최대 Heap 숫자를 의미하는 HEAP_SOURCE_MAX_HEAP_COUNT는 현재 3으로 되어 있다. 하지만 매크로 값을 변경하게 되면 현재 코드 구조에서도 Heap의 숫자는 쉽게 늘일 수 있도록 되어 있다. 이렇게 3개의 Heap을 생성하고 이를 다시 HeapSource 자료 구조를 통해서 관리하는 이유는 Process간의 메모리 공유를 극대화 하기 위함이다. 실제로 첫번째 Heap은 최초 Zygote이 초기화 되는 과정에서 생성되고 있으며, 두번째 Heap은 첫번째 fork가 실행되기 바로 이전에, 마지막 Heap은 fork 이후에 자식 process, 즉 application process에서 생성된다. 가령 마지막 Heap을 별도로 분리하지 않았다고 생각하면 Application 마다 전혀 다르게 활용되는 Heap으로 인해서 사실은 같은 내용을 담고 있는 Heap 영역까지도 영향을 받을 가능성이 크다. 즉, COW (Copy On Write)에 의해서 불필요한 메모리 낭비가 발생하게 된다는 말이다.
    • size_t numHeaps
      • HeapSource가 가지는 Heap의 현재 개수를 나타낸다. 궁극적으로는 3까지 증가하게 된다.
    • size_t externalBytesAllocated
      • Java 코드에 의해서 자동으로 할당되는 메모리가 아닌 JNI를 거쳐서 Native 코드 (C/C++)에서 할당된 메모리를 의미한다. Dalvik VM은 Process당 메모리 할당량을 통제하기 위해서 이러한 Native 메모리도 합산해서 관리하고 있다.
    • size_t externalLimit
      • external Allocation의 최대값을 나타낸다. 현재 Heap Utilization Ratio가 80%로 되어 있으며 할당/해제 발생시 이 비율에 의해서 externalLimit은 함께 업데이트 되고 있다. <용도 보충 설명!>
    • bool sawZygote


    GcHeap

    • dalvik/vm/alloc/HeapInternal.h


    HeapSource가 Heap자체에 대한 관리가 목적이라면 GcHeap은 이름 그대로 GC (Garbage Collection)을 하기 위한 정보를 담고 있는 자료 구조이다. 그렇기 때문에 GC의 대상이 되는 HeapSource 자료구조에 대한 포인터를 지니고 있으며 각종 Heap에 대한 리스트 및 GC 상태를 알려주는 변수를 포함하게 된다. 다음은 GcHeap 자료구조의 주요 멤버 변수 목록이다.
    • HeapSource      *heapSource
      • GC의 대상이 되는 Heap 메모리
    • HeapRefTable    nonCollectableRefs
      • GC 대상이 아닌 Heap Object의 리스트로서 이러한 Object들은 root 집합에 포함되어야 한다. root 집합이란 GC와 관련된 용어로서 다른 Object에 의해서 참조되지 않으면서 다른 Object를 참조하기만 한다는 뜻이다. 예를 들면 Stack 변수나 정적(Static) 변수 등이 그 대상이 될 수 있다.
    • LargeHeapRefTable  *finalizableRefs
      • Heap 중에서 GC될때 Finalization이 필요한 Object의 목록. Finalization이 곧 진행될 Object의 목록이 아니며 Class의 Instance처럼 Finalization이 발생할 수 있는 (java.lang.Object.finalize()를 override했음을 의미) Object를 지칭한다.
    • LargeHeapRefTable  *pendingFinalizationRefs
      • finalize()가 불려야 하는 Object의 목록으로서  gDvm.heapWokerListLock에 의해서 보호된다.
    • Object         *softReferences
      • java.lang.ref.Reference에서 상속된 softReference Class Intantance의 목록. Linked List 형태이며 ‘next’는 Reference.vmdata에 담겨 있다. GC 수행에 있어서는 가장 핵심적인 자료라고 볼 수 있다. soft/weak/phantom reference에 대해서는 별도로 설명하도록 하겠다.
    • Object         *weakReferences
    • Object         *phantomReferences
    • LargeHeapRefTable  *referenceOperations
      • 제거되어야 하거나 제거 대상 목록 (Reference Queue)에 포함될 Reference Object의 목록. 쉽게 말해서 GC의 대상이라고 봐도 무방하다.
    • Object *heapWorkerCurrentObject
    • Method *heapWorkerCurrentMethod
    • u8 heapWorkerInterpStartTime
    • u8 heapWorkerInterpCpuStartTime
    • struct timespec heapWorkerNextTrim
    • GcMarkContext   markContext
    • u8              gcStartTime
    • bool            gcRunning




    -----------------


    -------------------


    -----------------

  • 'Android 개발' 카테고리의 다른 글

    cts  (0) 2013.07.29
    android version  (0) 2012.06.28
    configure LMK killer  (0) 2012.02.02
    android porting on real target  (0) 2011.12.27
    android dumpsys 정리  (0) 2011.11.18
    And