반응형

현재 저는 코딩 시 필요한 경우 ChatGPT의 도움을 받고 있습니다. 코드 분석 요청에 대해 다른 AI 서비스들는 어떠한 결과를 보여주는지 비교해보았습니다.

 

이는 단편적인 비교이며, AI 서비스가 계속해서 개선되고 있는 상황이기 때문에 어떤 것이 우위에 있다고 말할 수는 없습니다. 하지만 궁금하기도 하고 이러한 경우에 어느 정도의 결과를 보여주는지 참고하시라고 글을 작성합니다.

 

Bing Copilot, Bard, Notion AI, ChatGPT에 동일한 질문을 해서 결과가 어떻게 나오는지 살펴보았습니다.

 

이전에 포스팅한 메모리 누수 관련 글(아래 참조)에서 각 AI에 테스트 코드의 메모리 누수 검토를 요청했습니다.

2018.09.16 - 메모리 누수(Memory Leak) 이야기 & LeakCanary 를 이용한 메모리 누수 검출

 

1. Bing Copilot

대화 스타일이 균형인 경우 처음에는 메모리 누수가 발생하지 않았다고 하다가 갑자기 뒤에서는 메모리가 해제되지 않는다라고 설명합니다.

메모리 해제하는 코드를 제시해주는 것으로 보아, 메모리 누수에 대해서 인지하고 해결책을 주지만 설명이 매끄럽지는 않습니다.

대화 스타일을 창의적으로 변경하면, 조금 다른 방법으로 답변을 주는데, 이 또한 메모리 누수를 해결하는 방법으로 적절한 답변입니다. 

대화 스타일을 정밀로 선택하면, 코드는 같이 보여주지 않지만, 간결하게 해결방법을 설명해주고 있습니다.

 

"코드를 수정해주세요"라고 된 버튼을 클릭하면, 아래처럼 수정된 코드를 보여줍니다.

2. Bard

제가 테스트한 시점에 Bard가 실험단계라고 알려줍니다. 그래서 그런지 좀 불안하고 갈팡질팡하는 답변을 보여줍니다.

앞서 Bing Copilot에 입력한 것과 동일한 내용을 프롬프트에 입력하니 "As a language model, I'm not able to assist ou with that" 답변을 주어, 마치 코드를 해석하고 분석하는 것을 지원하지 않는 것처럼 답변을 주고 있습니다.

하지만 내용을 달리해서 프롬프트에 이어서 다시 질문을 하니, 아래처럼 자신이 아직 개발 중인 상태라고 답변을 주고, 메모리 누수되는 부분을 찾아서 해결 방법을 제시해줍니다. 

왜 처음에는 제대로 답변을 하지 못했는지에 대해서 물으니 역시 "개발 중이고 학습상태"인데, 이전에 본 코드와 다르기 때문에 분석하지 못했다고 합니다. 음... 솔직하네요 ㅎㅎ

Bard는 향후 어떻게 더 발전할지 모르겠지만, 실험단계인 현시점에서 다른 AI 서비스 대비 여러번 질의해야 답변을 받을 수 있는 경우가 있을 것 같습니다.

 

3. Notion AI

Notion AI로 이렇게 코드를 분석해달라고 해본 적은 없었지만, 프로픔트에 요청한 결과, 잘못된 답변을 줍니다.

아무래도 Notion AI는 글쓰기, 글요약, 글의 내용을 향상하고 꾸미는데 최적화된 것 같다는 생각이 듭니다.

4. ChatGPT

어느 순간부터 코딩시 도움을 받을 때는 ChatGPT만 사용했는데, 결과물을 보니 당분간은 계속 ChatGPT를 사용하는 게 좋을 것 같다는 생각이 듭니다.

 

간결하면서 딱 필요한 설명을 하지만, 정확히 어느 부분을 수정했는지에 대한 커멘트까지 표시를 해줍니다.

앞서 말했듯이, 이는 단편적인 비교이고, 아직 개발중인 AI 서비스가 포함되어 있기에 현 시점에서는 ChatGPT가 우위에 있는 것으로 보이지만, 향후 다른 AI 서비스도 안정화되면 다시 한번 비교해보는 기회를 가져볼 것 입니다.

 

읽어주셔서 감사합니다.

반응형

 

 

 

1. Battery Service state (adb shell dumpsys battery) 정보

 

현재 폰의 배터리 상태를 알기 위해서 adb shell dumpsys battery 명령을 실행하면 아래와 같이 출력됩니다.

 

adb shell dumpsys battery
Current Battery Service state:
  mBootCompleted: true
  AC powered: false
  USB powered: true
  Wireless powered: false
  Max charging current: 0
  Max charging voltage: 0
  Charge counter: 0
  status: 2
  health: 2
  present: true
  level: 84
  scale: 100
  voltage: 4063
  temperature: 326
  technology: Li-ion
  batterySWSelfDischarging: false
  batteryMiscEvent: 0
  batteryCurrentEvent: 0
  mSecPlugTypeSummary: 2
  LED Charging: true
  LED Low Battery: true
  current now: 321
  charge counter: 0
  Adaptive Fast Charging Settings: true
USE_FAKE_BATTERY: false
SEC_FEATURE_BATTERY_SIMULATION: false
FEATURE_WIRELESS_FAST_CHARGER_CONTROL: true
  mWasUsedWirelessFastChargerPreviously: true
  mWirelessFastChargingSettingsEnable: true
LLB CAL:
LLB MAN: 20160426
LLB CURRENT: YEAR2018M9D15
LLB DIFF: 123
BatteryInfoBackUp
  mSavedBatteryAsoc: 77
  mSavedBatteryMaxTemp: 490
  mSavedBatteryMaxCurrent: 2872
  mSavedBatteryUsage: 176488
  FEATURE_SAVE_BATTERY_CYCLE: true

 

 

위의 각 항목에 관해서 설명하면 (단말기 제조사에서 추가해준 항목 제외) 아래와 같습니다.

AC Powered

 AC 어댑터 전원으로 충전여부

 

USB Powered

 USB 전원으로 충전여부

 

Wireless powered

무선충전기 전원으로 충전여부

 

Max charging current

최대 충전 전류

 

status

 1: 알수없음, 2: 충전중, 3: 방전중, 4: 충전완료후 충전중지, 5: 충전완료

 

health

 1: 알수없음, 2: 좋음, 3: 과열, 4: 불량  5: 과전압, 6: 불특정 실패, 7: 저온

 

present

 배터리 존재여부

 

level

 현재 배터리 레벨 (아래 scale 이 100일 경우 배터리양은 [level %] 로 읽으면 됨, 위의 경우 배터리양이 14%)

 

scale

 배터리 레벨의 최대값 (보통 100)

 

voltage

 현재 배터리 전압 레벨 (단위: mV)

 

temperature

 배터리 온도 (값을 10으로 나눠서 읽으면 됨, 위의 경우 28.9℃)

 

technology

 배터리 종류

 

 

2. 커널 메시지(kmsg) 배터리 정보

 

커널 메시지중에 배터리 정보를 얻기위해서 cat /proc/kmsg | grep battery 명령을 실행하면 아래와 같이 출력됩니다.

 

 

 

위 로그는 배터리를 모니터링 하는 데몬인 healthd에서 출력합니다.

 

l=59

현재 배터리 레벨

 

v=3878

 배터리 전압 레벨 (단위 mv)

 

t=25.0

 배터리 온도

 

h=2

 Health (1: 알수없음, 2: 좋음, 3: 과열, 4: 불량, 5:과전압, 6: 불특정 실패, 7: 저온)

 

st=3

 Status (1: 알수없음, 2: 충전중, 3: 방전중, 4: 충전완료후 충전중지, 5 충전완료)

 

c=-400

 현재 전류 (단위: mA, 마이너스(-)는 방전상태를 의미)

 

chg=

 충전기 종류 (' ': 충전상태아님, a: AC 어댑터 충전, u: USB 충전, w: 무선 충전) 

 

 

조금이나마 도움이 되셨으면 아래 공감 버튼을 눌러주세요.

반응형

 

메모리 누수 (Memory Leak) 이야기

 

간단하게 정의하면 앱에서 사용한 메모리를 반환하지 않는 현상입니다.

결과적으로 이후 가용 메모리가 줄어듭니다.

 

좀 더 자세히 설명하면, 안드로이드에서는 메모리가 부족하면 GC(Garbage Collector)가 동작해서 더는 유용하지 않는 객체들을 정리해서 메모리를 확보하게 됩니다.

 

그래서, 자바에서는 GC가 있기 때문에 메모리 누수가 없다고 하는데, 꼭 그런 것만은 아닙니다.

 

유용한 객체에서 유용하지 않는 객체를 참조(reference)하는 경우에 GC는 유용하지 않는 객체지만 제거할 수 없게 되어서 메모리 누수가 발생합니다. 

 

메모리 누수는 Exception이나 ANR 처럼 FC(Force Close) 되어서 문제가 있다는 것을 즉각 인지할 수 있는 것도 아니고, 직접적인 단서가 될 로그 정보가 있는 것도 아닙니다. 물론 누수가 심각해서 이후 메모리 할당을 못 할 경우 OOM(Out Of Memory) Exception까지 되는 경우도 있기는 합니다.

 

재현되는 경로가 확인되었고, 누수되는 메모리량이 커서 OOM 까지 되는 경우에는 그나마 인지할 수 있어서 다행이지만, 재현되는 경로 확인이 어렵고 누수되는 메모리량이 많지 않을 때에는 인지하기 어렵기 때문에 그대로 릴리즈될 수 있습니다.

 

이런 경우 문제는 메모리 누수가 있는 앱이 사용 빈도가 높을 경우 메모리 누수량이 계속 누적된다는 것입니다.

 

단말기 제조업체의 경우 QA에서 최종 릴리즈 전에 메모리 누수 테스트를 하고 있지만, 구글 플레이에 올라와 있는 앱들 중에서는 메모리 누수되는 앱들이 존재합니다.

 

이런 앱들은 사용자에게 어떤 영향을 미칠까요?

 

다운로드 한 앱들이 메모리 누수가 지속적으로 발생하게 되면 가용 메모리가 부족하게 되어 이후 메모리 확보를 위해서 GC가 동작하게 됩니다.

 

이때 화면이 렌더링 처리되어야 하는 16ms를 초과하는 GC시간이 빈번할 경우(특히 100ms 이상의 GC)에 일반적으로 버벅거린다고 말하는 Sluggish 현상을 사용자들이 경험하게 됩니다.

 

가용 메모리가 일정 수준 이하이면 LMK(Low Memory Killer) 를 트리거시킵니다. LMK 는 중요한 프로세스를 보호하기 위해서 중요하지 않은 프로세스를 Kill 후 메모리를 확보합니다. LMK 관련해서는 나중에 별도로 다룰 예정입니다.

 

최악의 경우 앞서 언급한 OOM 상황이 되면 다른 앱의 실행이 안 될 수도 있습니다.
많은 메모리 할당이 요구되는 앱들이 OOM으로 인한 FC로 괜한 오해를 받게 됩니다.

 

메모리 누수는 사용자 입장에서도 개발자 입장에서도 불편한 이슈입니다.

 

메모리 누수를 검출하는 많이 알려진 방법은 meminfo 나 procstats 명령을 통한 메모리양의 단순 비교로 메모리 누수 여부에 대해서 검출하는 것입니다. 하지만, 좀 더 편리하고 정확한 위치를 찾기 위한 툴들을 이용합니다.

 

Eclipse에서 안드로이드 개발할 때 DDMS(Dalvik Debug Monitor Server) 의 Heap dump와 Allocation Tracker를 이용했고, 플러그인 형태의 MAT(Memory Analysis Tool)를 사용해서 메모리 누수를 찾았습니다.

 

Android studio로 넘어오면서 Android Profiler라는 이름으로 CPU, MEMORY, NETWORK 항목들의 각 Profiler 가 통합되었고, MEMORY Profiler에서 이전 DDMS처럼 메모리 누수를 찾을 수 있었습니다.

 

이후 소개할 LeakCanary는 PC에서 동작하던 툴들과 달리 폰에서 메모리 누수가 있는 앱을 실행후 액티비티를 종료하게 되면 백그라운드 프로세스로 동작하면서 모니터링 후 메모리 누수가 검출시 Notificaiton으로 알려주기에 이전 툴들에 비해 사용이 쉽고 직관적입니다.

 

LeakCanary 를 이용한 메모리 누수 검출

 

먼저 LeakCanary 에 대한 간단한 설명을 하자면, 미국에 있는 Square라는 회사에서 메모리 누수를 검출하기 위해서 만든 라이브러리입니다.


참고로 이 회사는 모바일 지불 및 금융/가맹점 서비스 관련한 기업인데, 트위터 창업자 잭도시가 이 회사도 만들었습니다.

 

안드로이드 개발하면서 이 회사에서 공개한 라이브러리(Picasso, Moshi, OkHttp, Retrofit 등)를 알게 모르게 사용하거나 들어본 적이 있을 것입니다.


자사 앱의 메모리 누수를 해결하는 과정에 만들어진 라이브러리라고 하고, 이후 외부에 공개되었습니다.

 

LeakCanary는 액티비티가 종료(Destroy)되었지만, GC에 의해 회수되지 않는 메모리가 검출되면 별도의 프로세스에서 Heap Dump 후 hprof 파일로 저장하고 분석을 해서 결과를 리포트합니다. 

 

[LeakCanary 적용방법]

 

1. 아래 라이브러리를 build.gradle 화일에 추가합니다.

     LeakCanary는 Debug 모드에서만 동작합니다.

     Release 모드 라이브러리는 자바 쪽 LeakCanary 코드가 아무런 동작하지 않도록 처리되어 있습니다.

debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'

 

2. Custom Application class를 만들어주고, LeakCanary 설치 코드를 추가합니다.

package com.example.help.myapplication;

import android.app.Application;
import com.squareup.leakcanary.LeakCanary;

public class myapplication extends Application {

@Override
public void onCreate() {
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
LeakCanary.install(this);
}
}

android:name도 추가해줍니다.

<application
android:name=".myapplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

[LeakCanary 이용 메모리 누수 검출 테스트]

뷰나 액티비티를 static field로 참조하는 경우 액티비티가 종료되어도 GC로 메모리가 회수되지 않습니다.
아래의 경우 mText가 여기에 해당합니다.

public class MainActivity extends AppCompatActivity {
static TextView mText;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mText = new TextView(this);
mText.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
mText.setText(getString(R.string.app_name));
((ConstraintLayout) findViewById(R.id.mainActivityLayout)).addView(mText);
}
}

앞서 기술한 LeakCanary를 적용 후 앱 실행해서 액티비티를 종료하면 잠시후에 아래와 같이 Notification과 더불어 메모리를 Heap Dump 하고 있다고 알려주는 창이 나옵니다.

  

이때 Notification 창을 내려서 확인해보면 Heap Dump 완료 직후 분석을 진행하고 있습니다.
분석이 완료되면, 메모리 누수가 발생한 액티비티가 표시됩니다.

  

 

더 자세한 내용을 확인하기 위해서 Notification 창을 클릭하게 되면 아래와 같이 확인할 수 있습니다.

또한 Logcat을 통해서도 확인이 가능합니다.

프로젝트 압축화일  MyApplication.zip

이상으로 메모리 누수에 대한 이야기와 LeakCanary를 이용한 메모리 누수 검출방법에 대해서 알아보았습니다.

조금이나마 도움이 되셨으면 아래 공감 버튼을 눌러주세요.

+ Recent posts