There are lots of new features in the latest version of Android for developers to learn and users to explore.

Dan Rowinski  

http://readwrite.com/2013/11/07/android-kitkat-developers-users#awesm=~oog2XzEoqaTEoo

Google's introduction of Android 4.4 KitKat, the follow-on to three different versions of Android Jelly Bean, means that users have new features to look forward to—and that mobile developers and designers have a new toolset to learn.

KitKat is designed to work on a wide variety of devices with different amounts of RAM, even devices with as little as 512MB. But while memory optimization is the biggest change in this version of Android, KitKat also features a wide variety of new developer features and functions app makers will want to learn and exploit.

Here's an overview of the 10 most important new developer features in Android KitKat, many of which will also significantly change the ways users interact with Android phones and tablets.

Full-Screen Immersive Mode

KitKat full-screen immersive modeKitKat full-screen immersive mode

Apps in Android can now take expand to take advantage of every last pixel on the screen of a smartphone or tablet. Developers can choose to hide menu and navigation bars, buttons and other chrome to give users a true full screen app. Basically, developers can hide the entire system interface while the user is engaged in their apps.

This can be great for e-reader and other media apps (think newspapers or aggregation apps like Flipboard, Zite or Pulse) and games. To reveal the system user interface, KitKat has a new gesture where a user swipes from the top or the bottom to reveal navigation, menus and buttons.

Scene Transitions

Developers can now animate between “scenes”—different pages or events within and app—through a new transitions framework in KitKat 4.4. The new framework enables developers to define these scenes and animate them when a user enters or exits them within an app. This will allow apps to feature fades, resizing and other animations.

If developers don't want to individually manage animations and transitions by setting specific scenes, a function called TransitionManager can do it automatically within an apps view hierarchy.

Screen Recording

This is generally an awesome update in KitKat. Developers can create high quality video of their apps directly from an Android device. As the Google Play Android app store generally likes to have YouTube videos listed in its app descriptions, making it easy for developers to do this on a device (with an exterior camera) is a good idea.

The screen recording utility is provided within Android 4.4 and lets you capture video of your app and save it as an MP4 file. The recording can done at any device-supported resolution and then shared directly from the device to a computer for post-production. The screen recording function can be found through Android Debug Bridge (ADB) tool in the Android SDK or through the Android Studio integrated developer environment. 

Storage Access Framework

The new Storage Access Framework in KitKat allows users to browse and open documents in an app from a variety of cloud storage providers. Want to open a picture from Box, Google Drive, the device’s local storage or another third-party? The Storage Access Framework in Android 4.4 will handle that for you.

Cloud providers or local storage services (such as those offered by individual Android manufacturers) can use the new system by implementing a new document provider class within Android for their service. The document provider class within Android has the APIs (application programming interfaces) necessary to manage, browse, read or write documents within the app from a variety of sources.

Document types include audio and video files, pictures, text, wallpapers and more. Developers can add their own storage services to Android without having to do it on a specific vendor by vendor basis (such as an individual set up for HTC, Samsung etc.). 

New WebView & Chromium Features

KitKat includes new implementation of WebView based on Chrome for Android 30. It lets developers use the latest compatibility features, performance standards and support in WebView to access their Web-based content.

Chromium WebView supports many aspects of HTML5 as well as CSS3 and JavaScript. It uses JavaScript Engine (V8) to improve JavaScript performance. Google says that the new features and functions in WebView will work right away in KitKat 4.4 without any need to modify content.

New Near Field Communications Platform Support

The storage access framework allows for multiple sources of content integrationThe storage access framework allows for multiple sources of content integration

Host Card Emulation (HCE) in Android 4.4 is a new platform to support Near Field Communications (NFC) transactions. Google says that with HCE, “any app on an Android device can emulate an NFC smart card, letting users tap to initiate transactions with an app of their choice—no provisioned secure element (SE) in the device is needed.” Apps can also act in a new “Reader Mode” to receive NFC functionality (like payment processing, building access, tickets etc.).

The HCE is uses an Application Identifier (AID) to route the different NFC function from the hardware in a device to the right app. For instance, tapping your phone like you would a subway card is a lot different from tapping your phone at a retail store to pay for something. Apps can state what AIDs they want in what category such as payments or building access and so forth. HCE doesn’t replace the need for an NFC chip in a device, but it makes NFC more widely available and compliant.

Print API

The concept of “mobile printing” has been alive for some time, but we are now seeing much better integration into mobile devices. Microsoft has done well with wireless printing for mobile devices in Windows 8.1 and Windows 8.1 RT. Kitkat gets Android headed down the road to more ubiquitous printing as well.

Android apps will be able to print most types of content either through a Wi-Fi setup or through the cloud (where information is sent to the cloud from the device then back down to the printer). Google provides its own service for Android called Google Cloud Print. Android 4.4 introduces native platform support along with application programming interfaces for new types of printer support. Printer makers can use the APIs to make their devices compatible and build apps available in Google Play for users to download for specific printers. 

For compatibility, Android will turn documents into PDFs as the primary printing files. The printing API provides native and WebView support to turn documents into PDFs before sending them to the printer.

Infrared Blasters

Earlier in 2013, both HTC and Samsung created Infrared Blasters for their flagship devices so that you could control your television with your smartphone. At the time, the Android community wrung its hands about this because it wasn't a natively supported function in Android, just a manufacturer add-on built on top of Android. 

Google just changed that in KitKat. If any Android phone has infrared support, developers can tap into it and the application programming interface will tune the frequency from the phone to whatever remote receiver it is pointed at. Want to make an Android a universal remote? Now’s your chance. 

New Bluetooth Profiles

Two new Bluetooth profiles come to Android KitKat 4.4. The new profiles let apps support a bigger range of low-power devices and new media interactions. If you are familiar with your wonky Bluetooth functionality, the two new profiles are Bluetooth HID over GATT (HOGP) and Bluetooth MAP. Support for Bluetooth AVRCP 1.3 is also included.

Bluetooth HID over GATT provides a low-latency link to low-powered devices like computer mice or keyboards. Bluetooth MAP let’s apps exchange messages with nearby devices (say, a smartwatch, for instance). The new profiles and support add onto what Google built into Android with Bluetooth in Jelly Bean 4.2. 

A side note, Android 4.4 KitKat devices can now be certified by the Wi-Fi alliance as being Miracast compatible. That is a big step for Android in being able to stream content from a device to a television by supporting more streaming standards. Now only if the Chromecast supported Miracast. 

Low-Power Sensors

Android 4.4 has platform support for hardware sensor batching to optimize power consumed by various sensors. Google is working with hardware manufacturers to allow for collection and delivery of sensor data on an Android device while allowing device’s processor (CPU) to stay in low-power mode.

This should improve battery life and performance for sensor-driven applications. Ever want to take and track a 100-mile bike ride and finish up with a not-dead battery? This is Android’s solution. Let’s hope that it makes it into Android-powered smartwatches in the future.

The biggest example of this is the new step counter and detector for motion controlled sensors. The step detector uses the accelerometer to analyze how many steps you take during the day. The step counter keeps track of the total. These are available in the Nexus 5 and Google is working with manufacturers to bring the features to more devices. 

RenderScript Takes Advantage Of Device Hardware

RenderScript Compute was first introduced in Android Honeycomb 3.1. It is an application programming interface “designed to accommodate tasks that can be efficiently split and run concurrently on the underlying hardware which may be only known at the runtime of the application.” Essentially, it helps Android run faster and more efficiently by segmenting processes within an app. 

Graphical Processor Unit (GPU) acceleration that was introduced in Jelly Bean 4.2 is spreading to the rest of the Android ecosystem and will be supported on the Nexus 4 and Nexus 5. A new C++ API in the Android Native Developer Kit in KitKat 4.4 lets you access RenderScript through the Android platform framework. Big tasks that put a lot of pressure on the device’s hardware can now be integrated into an apps native code and allow for support from multiple smartphone CPU and GPU cores. 

What does that mean, exactly? Well, the knock against many quad-core smartphones is that most apps don’t take advantage of all the power the devices have to offer. The new functionality in RenderScript Compute in Android helps developers make more powerful apps while writing less code in order to get the most out of a device’s hardware.

LogFilter_1.4.jar

LogFilterCmd.ini

출처 : http://blog.naver.com/iookill/140135139931


자바로 만들었습니다. 플랫폼에 상관없이 돌아 갈겁니다. 사용법은 윈도우용과 동일합니다. 추가된 기능은 디바이스 여러게연결 되었을때 선택할 수 있게 했습니다.

 

1.4v : 창크기 저장

1.3v : Recent file 및 File open추가

1.2v : Tid 필터 추가

1.1v : Level F 추가

1.0v : Pid filter 추가

0.9v : 폰트 타입 추가

0.8v : 필터 체크 박스 추가

0.7v : 커널로그 파싱/LogFilter.ini에 컬러정의(0~7)

0.6v : 필터 대소문 무시

0.5v : LogFilterCmd.ini 추가

0.4v : add thread option, filter 저장

0.3v : 디바이스 선택 안되는 문제 수정

0.2v : Highlight기능 추가, Alt+L/R Click : Show/Remove tag

0.1v : 자바버전, 디바이스 선택

 

주요 기능

* Indicator추가(bookmark, error)

* 폰트 크기 변경

* 한글지원(UTF-8, UNICODE)

 

* logcat연동 : 단 환경설정에 adb.exe의 경로가 설정되어 있어야 한다.

* bookmark : Ctrl + F2(or 더블클릭) 키로 토글, F2/F3키로 bookmark간 이동

 북마크 설정시 북마크 메모 추가 가능

 

* bookmark 만 보기 : 죄측 상단의 체크박스 체크시 북마크된 라인만 보인다.

 

* column hide : 보기 싫은 컬럼 숨기기

 

* word filter (find/remove) : or 연산가능, 구분자는 '|'

 

* tag filter (show/remove) : word filter 와 동일

 

* log level filter : V/D/I/W/E or 연산가능

 

* goto line : 라인이동

 

* copy : 선택라인 클립보드 복사, 다중선택가능, 복사할 컬럼 선택가능

            선택라인 우클릭시 해당 컬럼만 복사

 

* 저장된 로그(logcat, DDMS) drag&drop으로 보기 가능

출처 : http://shadowxx.egloos.com/10781292


안녕하세요멀티미디어팀에 이상철입니다.

 

오늘은 여러분들이 프로젝트를 진행하면서 한번을 들어 볼(?) OOM (Out of Memory)  LMK (Low Memory Killer) 에 대한 이야기를 해볼까 합니다.

 

오늘 이야기는 예전에 제가 보내드렸던 "[Android] Background process 줄여서 Memory 확보로 성능 개선하기." 메일과 관련이 깊은 내용입니다.

 

사실 이번 이야기는 제 동기가 찾아서 보내준 내용을 제가 여러분들과 공유하고자 전송해드리는 정도입니다.

 

간단히 정리하면, OOM  Linux 커널에서 예전부터 쭈~욱 있어왔던 메모리 관리 모듈이고 이게 휴대기기에 들어가는 system 에서는 안맞다고 생각해서 OOM 이 일어나지 않도록 메모리를 관리하자라고 생각해서 Android 에서 만든게 LMK 입니다.

, Android 에는 LMK  OOM 이 다 있고 동작합니다하지만 OOM 이 발생되면 파급 효과(? - 아래 글을 읽어보면 이해가 되실 것입니다가 크기 때문에 미연에 이러한 것을 방지하고자 동작되는 것이 LMK 라고 보시면 됩니다.

 

아래는 제 동기 최종한 선임이 보내준 내용입니다.

======================================

Android memory management

0. OOM Killer
- linux kernel
의 메모리 부족시 메모리 확보를 하는 process
- src 
위치 : mm/oom_kill.c

기본 설명 :
시스템 구동중 메모리가 부족하면 운영체제 내부의 우선순위 알고리즘에 의해 프로세스를 죽인다.
리눅스 커널은 프로세스의 메모리 할당시 남은 메모리가 없는 상황을 처리하기 위해 OOM(Out of Memory) Killer 를 가지고 있다
그 것은 모든 프로세스를 어떤 제약으로 점수를 매겨 init을 제외한 최고 점수의 프로세스는 죽여 메모리를 확보한다.
따라서 일반적으로 서버를 운영할때에는 서비스데몬이 oom-killer에게 안죽도록 메모리관리를 잘해야한다

- Wiki OOM
most cases, a computer with virtual memory support where the majority of the loaded data resides on the hard disk would probably run so slowly due to excessive paging that it would be considered to have failed, 
prompting the user to close some programs or reboot. As such, an out of memory message is rarely encountered by applications with modern computers
The typical OOM case in modern computers happens when the operating system is unable to create any more virtual memory, because all of its potential backing devices have been filled. 
Operating systems such as Linux will attempt to recover from this type of OOM condition by terminating a low-priority process, a mechanism known as the OOM Killer


- OOM 
발생 원인
커널은 Virtual memory를 이용한 메모리 할당을 하므로 실제 가용한 physical 메모리 보다 큰 프로그램 size의 메모리를 할당 할 수 있다
즉 프로그램에서 당장 사용하지 않는 메모리는 나중에 메모리를 할당하기 때문에 실제 사용 가능한 메모리를 넘는process load될 수 있다.(이것을 overcommit 이라 한다.) 
만약 overcommit된 메모리에 실제 뭔가 쓰여지기 시작하면 메모리가 모자라므로 Out of memory가 발생한다.

- OOM Killer Configure
/proc/meminfo/CommitLimit : Commit Limit / SWAP + SOME REAL MEMORY
/proc/meminfo/Committed_AS : 
현재 Commited 된 양
/proc/sys/vm/overcommit_memory : (mode 0 - heuristic / mode 1 - always overcommit / mode 2 - strict overcommit, overcommit 
불가)
/proc/sys/vm/overcommit_ratio : The percentage can be more than 100, for a situation where you have lots of programs that don't use much of their allocated space.(percentage of real memory)

- Kill Policy
* The formula used is relatively simple and documented inline in the
* function. The main rationale is that we want to select a good task
* to kill when we run out of memory.
*
* Good in this context means that:
* 1) we lose the minimum amount of work done
* 2) we recover a large amount of memory
* 3) we don't kill anything innocent of eating tons of memory
* 4) we want to kill the minimum amount of processes (one)
* 5) we try to kill the process the user expects us to kill, this
* algorithm has been meticulously tuned to meet the principle
* of least surprise ... (be careful when you change it)

- Comment
기본적으로 OOM은 적은 수의 프로세스를 죽여서 많은 양의 메모리를 확보할 수 있는 heuristic을 쓰는 것을 알 수 있다.
OOM killer
 heuristic에 기반하고 있기 때문에중요한 server process가 죽지않는 다는 보장을 하기가 힘들다
하지만, OOM killer를 쓰지 않는다고 하더라도특정 프로세스가 종료할 때까지 기다리는 수 밖에 없고,
page fault handler
에서 page frame을 할당받지 못하면, init를 제외한 해당 task kill 되기 때문에, OOM 상황에서는 어차피 치명적인 상황이 발생한다.
따라서, OOM 상황이 발생하지 않도록 노력하는 것이 중요하여 이때문에 안드로이드에서는 별도로 LMK를 사용하고 있다.

- Reference site
http://blog.naver.com/PostView.nhn?blogId=pinocc&logNo=120059187934
http://blog.naver.com/newbeing2000/30036826720
http://lechuck.tistory.com/38
http://andstudy.springnote.com/pages/3667993

 

1. Low Memory Killer
안드로이드에 특화된 OOM
- src
위치 : /drivers/staging/android/lowmemorykiller.c(공식 커널에선 제외되어 안드로이드 커널에서만 볼 수 있다.)

기본설명
low memory killer
는 구글 직원이 2009년에 안드로이드 메모리 관리를 위해 작성한 리눅스 커널 모듈이다
이 커널이 등장한 배경은 리눅스 메모리 정책이 현재 임베디드 환경에 맞지 않다는 것이다
리눅스 커널의 기본 메모리 정책은 OOM Killer로 대표되는데 메모리가 부족한 상황에서 최대한의 가용성을 확보하기 위해 가상 메모리를 가장 많이 할당한 프로세스를 죽이는 형태로 되어 있다
이런 정책은 서버나 임베디드 환경에서 주요 서비스나 주요 어플리케이션을 죽일 수 있다.
안드로이드의 가용 RAM이 설정된 Threshold 이하로 떨어지게 되면 프로세스 중요성별로 분류된 6가지 그룹중 해당Application Kill 하도록 설정되어 있습니다.
그래서 시스템을 최종 사용자(end user) 관점에서 안정적이게 만든다

-Application
 6가지 타입으로 분류

- LMK Configure
# cat /sys/module/lowmemorykiller/parameters/adj
cat /sys/module/lowmemorykiller/parameters/adj
0,1,2,4,7,15
# cat /sys/module/lowmemorykiller/parameters/minfree
2048,3072,4096,6144,7168,8192
위 값은 4KB 페이지 단위로 표현된 것을 보여준 것이고, 4번째 값인 7168 HIDDNE_APP  Threshold에 해당
가용 RAM 7168 * 4K = 29M로 줄어들어야 HIDDEN_APP Kill 하도록 설정되어 있음
이 값은 /init.rc에 표기되어 있음


- Kill Policy
1. 
어플리케이션은 자신의 상태(adj)를 항상 가지고 있는다. (/proc/<pid>/oom_adj) 
2. 
운영체제는 몇개의 메모리 문턱(minfree)을 가지고 있어서 단계로 메모리 문제를 다룬다
3. 
운영체제는 어플리케이션의 상태 변화를 인지하여 어플리케이션 상태를 수정한다
4. adj
 minfree 값은 짝을 이룬다. (0, 1024) (8, 4096) 
5. minfree
값 이하로 메모리가 남은 경우 adj 값 이상의 어플리케이션을 제거한다. (4096 페이지 이하일 경우 adj  8이상의 어플리케이션 중 하나가 제거된다.) 
6. adj 
값이 높을 수록 먼저 제거되고 차순으로는 가상 메모리 양을 비교한다. (4096 페이지 이하일 때 8 10이 있을 경우 10이먼저 제거된다.) 
*3
번 과정인 어플리케이션 상태 수정은 유저 레벨 서비스인 ActivityManager가 변경한다
어플리케이션 상태는 GUI와 깊은 연관이 있기 때문에 커널 레벨에서 일방적으로 결정하기에는 부적절하다

- Reference
http://barriosstory.blogspot.com/2009/02/taming-oom-killer.html
http://s2junn.tistory.com/45
http://dalinaum-kr.tumblr.com/post/4528344482/android-low-memory-killer

 

이상입니다.

출처 : http://lucidtale.wordpress.com/?s=Android+Low+Memory+Killer


OOM killer & Android LMK

현재 리눅스 커널에는 OOM(Out of Memory) killer가 있다.  소스 파일 위치는 mm/oom_kill.c 이며

메모리가 부족해서 할당에 실패할 경우

alloc_pages -> … -> out_of_memory() -> select_bad_process() -> badness() 가 불리게 된다.

bad process의 선정은 다음과 같다.

/*
* The baseline for the badness score is the proportion of RAM that each
* task’s rss, pagetable and swap space use.
*/
points = get_mm_rss(p->mm) + p->mm->nr_ptes +
get_mm_counter(p->mm, MM_SWAPENTS);

/* Normalize to oom_score_adj units */
adj *= totalpages / 1000;
points += adj;

rss(Resident Set Size)는 프로세스와 관련된 physical page의 갯수라고 볼 수 있다. adj는 user에서 설정가능한 값이며 /proc/[pid]/oom_score_adj 를 통해 설정 가능하다. totalpages는 physical mem + swap mem 이라고 보면 된다.(코드를 보면 이렇게 단순하지는 않다.)

어쨋든 point가 높을수록 bad process 이며 메모리를 많이 사용하는것을 우선적으로 죽이는 것을 알 수 있다. 그 이유는 다음과 같다.

 * Good in this context means that:
 * 1) we lose the minimum amount of work done
 * 2) we recover a large amount of memory
 * 3) we don't kill anything innocent of eating tons of memory
 * 4) we want to kill the minimum amount of processes (one)
 * 5) we try to kill the process the user expects us to kill, this
 *    algorithm has been meticulously tuned to meet the principle
 *    of least surprise ... (be careful when you change it)
 */

즉, 가장 적은 프로세스를 죽여서 가장 많은 메모리를 확보하는 것이 목적이며 user의 의견도 반영하기 위해 oom_score_adj를 설정할 수 있게 해놓았다. 이것이 커널 입장에서는 효율적이라고 볼 수는 있지만 유저의 입장에서는 그렇지 않을 수 있다. 그리고 oom_killer는 정말 메모리가 없는 마지막중에 마지막에 불리기 때문에 너무 늦은 감이 있다.(자기 자식같은 프로세스를 죽이는게 좋진 않겠지…)

그래서 안드로이드에서는 LMK(Low Memory Killer)를 따로 만들어서 유저의 입장에서 죽여도 괜찮은 프로세스를 골라 kernel oom 이 불리기전에 프로세스를 죽여 메모리를 확보한다. 그래서 안드로이드에는 kernel oom killer도 있고 Low memory killer도 있다. oom killer는 대충 이쯤 보고 다음 시간에 LMK를 집중해서 보도록 하자.

* 참고 문서 & 홈페이지

http://barriosstory.blogspot.kr/2009/02/taming-oom-killer.html

http://linux-mm.org/OOM_Killer

http://shadowxx.egloos.com/10781292


ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES : OOM을 자동으로 결정 해주는 피쳐 


Android Low Memory Killer(1)

일단 Android가 LMK를 어떻게 활용하는지 그 방법을 알아보도록 하자.

Android에서

/sys/module/lowmemorykiller/parameters/adj 의 값을 읽어보면

0, 58, 117, 235, 529, 1000 <- 요렇게 나온다.

/sys/module/lowmemorykiller/parameters/minfree 의 값은 다음과 같다.

8192, 10240, 12288, 14336, 16384, 20480

위 설정값은 Activity Manager가 하게 되는데 adj 값과 minfree의 각 필드값이 짝을 이룬다. 이 값들로 종료해야 할 프로세스를 결정한다.

예를들면 현재 남은 page의 갯수가 16384개 이하(64MB)가 됐을때 adj가 529 이상인 process를 죽인다.  더 사용하다가 page갯수가 10240 이하면 이번에는 adj가 58 이하인 프로세스를 죽이게 된다.  각 app의 adj 값은 Activity Manager가 정해주게 되며 /proc/pid/oom_score_adj(또는 oom_adj)에 써주게 된다.

Activity Manager는 각 app을 다음과 같이 분류해서 adj 값을 정한다.

HIDDEN_APP_MAX_ADJ = 1000

HIDDEN_APP_MIN_ADJ = 529

BACKUP_APP_ADJ = 235

PERCEPTIBLE_APP_ADJ = 117  // ex) background music playback

VISIBLE_APP_ADJ = 58

FOREGROUND_APP_ADJ = 0

ps) oom_adj라는 것과 oom_score_adj 라는 것이 있다.  oom_adj값은 과거에 쓰던 값이며 과거 버전과의 호환성을 위해 남겨놓은 값이다.  거의 의미는 같은데 oom_adj는 -16 ~ 15 사이의 값을 가지며 oom_score_adj는 -1000 ~ 1000 사이의 값을 가진다.  커널에서 먼저 바꾼듯 한데 안드로이드는 아직 oom_adj를 쓰고 있다. 그래서 안드로이드가 oom_adj에 값을 쓰면 알아서 oom_score_adj에 값이 설정된다.

참고 소스 위치(Android 4.2) : frameworks/base/services/java/com/android/server/am/ProcessList.java


Android Low Memory Killer(2)

android low memory killer의 소스는 간단하다.

LMK에서 구현한 memory shrinker 함수인 lowmem_shrink 함수를 register_shrinker() 를 통해 등록하는 것과

/sys/module/lowmemorykiller/parameters/ 에 노드를 만들어 주는 것이 전부이다.

이렇게 shrinker를 등록해놓으면 kernel에서 memory가 부족할 때  등록된 shrinker들을 불러준다.

lowmem_shrink 함수에서 하는일은 죽일 프로세스를 선정하는 일인데 일단 가장 oom_score_adj가 큰것을 찾고

만약 oom_score_adj가 같으면 rss가 더 큰 프로세스를 찾아 SIGKILL 을 날린다. shrinker 함수가 한번 불리면 여러개를

한꺼번에 죽이지는 않고 하나씩만 죽인다.

RSS(Resident set size) : the portion of a process’s memory that is held in RAM. The rest of the memory exists in swap or the filesystem(never loaded or previously unloaded parts of the executable.

즉 RSS란 순수하게 물리 메모리를 차지하고 있는 용량이다. 다음에는 RSS등과 같은 메모리 측정 관련 용어들을 알아보자

커널 소스 경로(3.4) :  drivers/staging/android/lowmemorykiller.c

출처 : http://anzero.blog.me/89651858


안드로이드 소스를 빌드해서 생성하면 dalvik문서가 생성되는데,

Android site에서는 공개되지 않은 것 같다.
dalvik vm 목적, 구현 mechanism, prepared dex등으로 구성되는데,
관심사순으로 재구성하여 발췌하였다.

There are at least three different ways to create a "prepared" DEX file, sometimes known as "ODEX" (for Optimized DEX):

  1. The VM does it "just in time". The output goes into a special dalvik-cache directory. This works on the desktop andengineering-only device builds where the permissions on the dalvik-cache directory are not restricted. On production devices, this is not allowed.
  2. The system installer does it when an application is first added. It has the privileges required to write to dalvik-cache.
  3. The build system does it ahead of time. The relevant jar / apk files are present, but the classes.dex is stripped out. The optimized DEX is stored next to the original zip archive, not in dalvik-cache, and is part of the system image.

The dalvik-cache directory is more accurately $ANDROID_DATA/data/dalvik-cache. The files inside it have names derived from the full path of the source DEX


The goals led us to make some fundamental decisions:

  • Multiple classes are aggregated into a single "DEX" file.
  • DEX files are mapped read-only and shared between processes.
  • Byte ordering and word alignment are adjusted to suit the local system.
  • Bytecode verification is mandatory for all classes, but we want to "pre-verify" whatever we can.
  • Optimizations that require rewriting bytecode must be doneahead of time.

They also run Linux, which provides virtual memory, processes andthreads, and UID-based security mechanisms.

The features and limitations caused us to focus on certain goals:

  • Class data, notably bytecode, must be shared between multiple processes to minimize total system memory usage.
  • The overhead in launching a new app must be minimized to keep the device responsive.
  • Storing class data in individual files results in a lot of redundancy, especially with respect to strings. To conserve disk space we need to factor this out.
  • Parsing class data fields adds unnecessary overhead during class loading. Accessing data values (e.g. integers and strings) directly as C types is better.
  • Bytecode verification is necessary, but slow, so we want to verify as much as possible outside app execution.
  • Bytecode optimization (quickened instructions, method pruning) is important for speed and battery life.
  • For security reasons, processes may not edit shared code.

출처 : http://iamyooon.tistory.com/86


안드로이드 디바이스를 사용하는 도중

터치는 동작하지만 화면이 refresh되지 않는 문제를 경험한 적이있다.

디버그메시지를 살펴보니 stop_drawing_early_suspend: timeout waiting for userspace to stop drawing

라고 warning메시지를 띄우는것을 볼 수있었다.



kernel/kernel/power/fbearlysusepnd.c에는 

early suspend 진입시에 호출되는 stop_drawing_early_susepnd()가 있다.



이 함수에서는 fb_state변수를 FB_STATE_REQUEST_STOP_DRAWING으로 설정한 다음 

HZ시간 동안 해당 변수가 FB_STATE_STOP_DRAWING으로 변경되길 기다린다.

시간 안에 값이 변경되지 않을 경우 위 에러메시지를 출력하게 된다.



변수 fb_state는 동일 파일내에 있는 wait_for_fb_wake_show()에 의해  변경된다. 

좀 더 자세히 이야기하자면 wait_for_fb_wake_show()는  

/sys/power/wait_for_fb_wake 파일을 read하였을 때 호출되도록 아래와 같이 정의되어 있다.(동일한 파일에 정의됨)


#define power_ro_attr(_name) \
static struct kobj_attribute _name##_attr = {   \
        .attr   = {                             \
                .name = __stringify(_name),     \
                .mode = 0444,                   \
        },                                      \
        .show   = _name##_show,                 \
        .store  = NULL,         \
}

power_ro_attr(wait_for_fb_sleep);
power_ro_attr(wait_for_fb_wake);



wait_for_fb_wake파일은 

frameworks/base/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp의

threadLoop() 메소드에서 아래와 같이 사용한다.(read된다.)


static char const * kSleepFileName = "/sys/power/wait_for_fb_sleep";
static char const * kWakeFileName = "/sys/power/wait_for_fb_wake";

 bool DisplayHardwareBase::DisplayEventThread::threadLoop()
{
    fd = open(kSleepFileName, O_RDONLY, 0);
    ...
    err = read(fd, &buf, 1);
    ...
    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
    if (err >= 0) {
            ...
            flinger->screenReleased(0);
            ...
    }

    fd = open(kWakeFileName, O_RDONLY, 0);
    ...
      err = read(fd, &buf, 1);
    ...
    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
    if (err >= 0) {
        ...
        flinger->screenAcquired(0);
        ...
    }
}


두번째 read() 호출에 의해 wait_for_fb_wake파일이 read되고 wait_for_fb_wake_show()를 호출하게 되는 것이다.

코드를 봐서 알겠지만 screenAcquired()가 본 문제와 밀접한 관계가 있다.

확실하진 않지만 screenAcquired()는 결국 acquireScreen()를 호출하여 mCanDraw를 true로 설정하는 것으로 보인다.

안드로이드에서는 변수 mCanDraw가 true로 변경되어야 surface flinger가 화면업데이트를 할 수 있는 것이다.



read()호출이 반드시 성공하여야 screenAcquired()가 호출되고 화면이 갱신되는 구조는 

개인적으로는 바람직해 보이지 않아 보인다.

실패할 경우 디바이스를 재부팅하지 않고서는 정상적인 사용이 불가능하기 때문이다.



좀 더 근본적인 문제는 open()과 read()가 정상적으로 작동하지 않는 것에 있다.

suspend에 진입하면서 filesystem에 문제가 생기는 것인지, 어떤 타이밍 문제인지는 모르겠지만

가끔 open()이 0을 리턴하고 이 file descriptor를 이용해 read()를 호출하니 에러가 발생한다.


이유를 못찾고 임시방편으로 read()결과와 상관없이 screenAcquired()를 호출하도록 수정하였다.

하루종일 테스트하였지만 아직까지는 문제가 없다.



출처 : http://goodidea.tistory.com/86

 Java에서 서블릿을 이용하는 경우에는 쿼리 문자열 값 이나, 호스명, 포트 등은 각각 getParameter() ,getServerName(), getServerPort() 등의 메소드를 이용하여 값을 읽어내면 간단하지만 직접 URL을 핸들링해야 하는 경우가  가끔씩 있다.  URL Rewriting을 하고자 한다거나, 경로에 파라메터를 넣고자 하는 경우 이거나 아니면 직접 웹서버를 구현하는 경우라던가 등.

그래서 이번에는 간단하게 URL로 부터 값을 뽑아 내는 방법으로 정규식 (Regular Expression)을 이용하는 방법을 정리 해보고자 한다.
 
더불어 정규식 사용방법을 익히는데도 도움이 되도록 가능하면 상세하게 설명을 달것이다.

URL(Uniform Resource Location)에의 구성은 기본적으로 아래와 같은 구조를 갖는다.

 scheme://username:password@domain:port/path?query_string#anchor

여기에서는 사용자명과 패스워드를 입력받는 경우는 생략하고 scheme 에는 http, https 가 들어오는 경우만 처리하는 것으로 한다.

즉 아래와 같은 경우 만 target으로 할 것이다.
 scheme://domain:port/path?query_string#anchor


  정규식을 활용하는 방법은 다량의 텍스트에서 원하는 패턴만 찾아내고자 할때가 있지만 찾아낸 문자열에서 다시 세부 요소를 뽑아 내고자 하는경우에도 활용 할 수 있다. 

  예를 들어 HTML 텍스트에서  <a href="someurl">someurl go!</a>  형태와 같은 <a> 태그를 를 찾아 내고자 하는 경우도 있지만 실제 활용단계에서는 href="" 안에 있는 값을 바로 뽑아 낼 수 있는게 필요하다.

마찬가지로 URL에 정규식의 적용도 실제 URL내에 있는 스키마, 호스트(도메인)명, 포트, 경로, 쿼리문자열, 앵커(anchor)을 추출하는게 실제 의미가 있다.

이러한 경우를 위해 정규식에서는 ()를 이용한 그룹핑을 지원한다. 따라서 각 추출하고자 하는 요소를 () 묶어 주기만 하면 된다.

첫번째 스키마, 스키마는 http와 https 인경우만 처리하기로 했으므로  http:// 또는 https:// 를 찾기 위해

   ^(https?):\/\/

     's'문자는 는 생략가능이고, '/'문자를 Escape 하기 위해 \를 앞에 붙였다. '^' 줄의 시작위치를 뜻한다.

두번째 도메인(호스트)명, 도메인명에는 영숫자, '-'  와 '.' 가 올 수 있다. '_' 문자는 맨 앞에 못오거나 하는 규칙이 있지만 URL을 파싱하려는 서비스에 도달했다는 의미는 정상적인 URL이므로 복잡한 비정상적인 경우는 생각할 필요는 없다.
그래서  콜론(:), 슬래시(/), 빈칸(' ')을 뺀 나머지 문자열이 하나 이상 나타난다고  표현해주면된다.
([^:\/\s]+)

세번째, 포트 포트는 ":8080" 형태로 콜론뒤에 숫자가 나온다. 숫자의 길이는  경로가 시작되는 다음 슬래시(/) 앞까지다. 그리고 포트 값은 생략될 수 있으므로 그룹핑 괄호 뒤에 물음표(?)를 해준다. 안쪽 괄호는 이후 ':"를 뺀 포트값만 추출하기 위함이다.

(:([^\/]*))?

네번째 경로다. 경로는 반드시 슬래시(/)로 시작하고 빈칸과 슬래시가 아닌문자들인 것을 한다. 경로는 반복될 수 있으므로 ()에 *를 붙이고,  중간경로 없이 바로파일명으로 넘어 갈 수 있으므로 물음표를 붙인다.

((\/[^\s/\/]+)*)?

다섯번째 파일명자리는 빈칸, 물음표, 또는 앵커표시인 샵(#)이 나올때까지 거나 아니면 문자열 맨끝까지 이다.
파일명은 마지막 슬래시로 시작해서 빈칸이나 물음표가 아닌문자들이 올 수 있는 것으로 한다. 파일명 문자열은 없을 수 도있으므로 (전체 URL에 경로 / 문자로 끝나는 경우) * 로 문자열 뒤에 붙이고
\/([^#\s\?]*)

여섯번째 쿼리자리는 물음표부터 샵이나오거나 문자열 끝까지 이고 생략될 수 있으므로
(\?([^#\s]*))?

앵커는 샵으로 시작하는 문자열이고 생략될 수 있으므로
(#(\w*))?

마지막으로 문자열의 끝 표시 $를 붙여 준다.
$

최종적으로 앞서 정리한 자리들을 모두 합쳐주면 다음과 같이 된다.
^(https?):\/\/([^:\/\s]+)(:([^\/]*))?((\/[^\s/\/]+)*)?\/([^#\s\?]*)(\?([^#\s]*))?(#(\w*))?$


아래는 java로 작성한 sample 코드.  자바에서 '\' 문자를 다시 escape 해주기 위해 "\\" 로 바뀌었다.

public void extractUrlParts() {
   
String testurl = "https://goodidea.tistory.com:8888/qr/aaa/ddd.html?abc=def&ddd=fgf#sharp";
 
//                                     http:       //  도메인명             :포트                     경로                                파일명                    쿼리                         앵커



   
Pattern urlPattern = Pattern.compile("^(https?):\\/\\/([^:\\/\\s]+)(:([^\\/]*))?((\\/[^\\s/\\/]+)*)?\\/([^#\\s\\?]*)(\\?([^#\\s]*))?(#(\\w*))?$");



   



   
Matcher mc = urlPattern.matcher(testurl);
   
   
if(mc.matches()){
           
for(int i=0;i<=mc.groupCount();i++)
                   
System.out.println("group("+i+") = "+mc.group(i));
   
}
   
else
           
System.out.println("not found");
}

 

이렇게 해서 실행시키면 다음과 같은 결과가 나오다.


group
(0) = https://goodidea.tistory.com:8888/qr/aaa/ddd.html?abc=def&ddd=fgf#sharp
group
(1) = https
group
(2) = goodidea.tistory.com
group
(3) = :8888
group
(4) = 8888
group
(5) = /qr/aaa
group
(6) = /aaa
group
(7) = ddd.html
group
(8) = ?abc=def&ddd=fgf
group
(9) = abc=def&ddd=fgf
group
(10) = #sharp
group
(11) = sharp


mc.groupCount()는 정규식내에 괄호의 수 만큼 그룹핑을 하게 되고 배열(mc.group)의 각 그룹의 인덱스는 고정이며 해당 위치별로 [1]은 스키마, [7]은 파일명이 되는 것이다.

설치하면서 적은 글이여서 잘되리라 본다. (MacBook Pro에 설치)

1. ubuntu 12.04.1 를 설치한다. 반드시 64 bt 버전을 설치해야 한다. 최소 메모리는 8GB 는 있어야 하고 swap도 2G이상 잡아두는것이 좋다.

2. 빌드에 필요한 기본 패키지를 설치한다.

$ sudo apt-get install git-core gnupg flex bison gperf build-essential \
  zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
  libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
  libgl1-mesa-dev g++-multilib mingw32 tofrodos \
  python-markdown libxml2-utils xsltproc zlib1g-dev:i386 \
  gcc-4.4 g++-4.4 gcc-4.4-multilib g++-4.4-multilib
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

3.  Java SE 6 JDK를 설치한다. 

http://www.oracle.com/technetwork/java/javase/downloads/index.html  에 접속후 
Java SE 6 Update 35 옆의 다운로드 버튼을 클릭해서 Linux x64 버전을 다운받은 후 설치한다.
현재 파일명은 : jdk-6u35-linux-x64.bin

$ chmod +x jdk-6u35-linux-x64.bin $ sudo ./jdk-6u35-linux-x64.bin $ sudo mkdir -p /usr/lib/jvm $ sudo mv jdk1.6.0_35 /usr/lib/jvm/ $ sudo ln -s /usr/lib/jvm/jdk1.6.0_35/ /usr/lib/jvm/java-6-sun $ sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_35/bin/java 1 $ sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_35/bin/javac 1 $ sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.6.0_35/bin/javaws 1 $ sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk1.6.0_35/bin/jar 1

아래 4개는 기존에 자바가 깔려 있을 경우만 $ sudo update-alternatives --config java $ sudo update-alternatives --config javac $ sudo update-alternatives --config javaws $ sudo update-alternatives --config jar

$ java -version 으로 버전 확인시 아래처럼 나오면 됨 java version "1.6.0_35" Java(TM) SE Runtime Environment (build 1.6.0_35-b10) Java HotSpot(TM) 64-Bit Server VM (build 20.10-b01, mixed mode)

4. GCC를 설정 한다.

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 40 \ --slave /usr/bin/g++ g++ /usr/bin/g++-4.6 $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 80 \ --slave /usr/bin/g++ g++ /usr/bin/g++-4.4 $ sudo update-alternatives --config gcc 실행시 목록 나오면 4.4.x 선택하면 된다 (0번)

$ gcc --version 으로 아래처럼 버전 나오면 됨 gcc (Ubuntu/Linaro 4.4.7-1ubuntu2) 4.4.7 Copyright (C) 2010 Free Software Foundation, Inc.

5. 커널/부트 빌드를 위해 컴파일러를 설치한다.

wget -c http://www.codesourcery.com/sgpp/lite/arm/portal/package6488/public/arm-none-linux-gnueabi/arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 sudo mkdir -p /opt/toolchains sudo tar -C/opt/toolchains/ -jxvf arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 sudo ln -s /opt/toolchains/arm-2010q1/ -t /opt/

6. CCACHE 설정

Setting up ccache

You can optionally tell the build to use the ccache compilation tool. Ccache acts as a compiler cache that can be used to speed-up rebuilds. This works very well if you do "make clean" often, or if you frequently switch between different build products.

Put the following in your .bashrc or equivalent.

export USE_CCACHE=1

By default the cache will be stored in ~/.ccache. If your home directory is on NFS or some other non-local filesystem, you will want to specify the directory in your .bashrc as well.

export CCACHE_DIR=<path-to-your-cache-directory>

The suggested cache size is 50-100GB. You will need to run the following command once you have downloaded the source code.

prebuilt/linux-x86/ccache/ccache -M 50G