안드로이드 게임 프레임을 adb로 재는 방법을 검색하면 거의 전부 이 명령어가 나옵니다.
그런데 3D 게임에 쓰면 0이 나옵니다. 명령어가 틀린 게 아니라, 애초에 그 게임을 측정할 수 없는 도구입니다. 실제로 되는 방법을 실기기에서 확인해 정리했습니다.
결론부터
- dumpsys gfxinfo는 언리얼·유니티 같은 3D 게임의 프레임을 못 잽니다. 오류도 안 나고 그냥 0이 나옵니다.
- 되는 건 dumpsys SurfaceFlinger --timestats입니다. 레이어별 averageFPS를 소수점까지 줍니다.
- 루팅 필요 없습니다. USB 디버깅만 켜면 됩니다.
1. gfxinfo가 0을 뱉는 실제 화면
먼저 초기화하고, 게임을 30초간 돌린 뒤 읽었습니다.
adb shell dumpsys gfxinfo com.com2us.es.android.google.kr.normal reset
(30초 대기)
adb shell dumpsys gfxinfo com.com2us.es.android.google.kr.normal
결과입니다.
Total frames rendered: 0
Janky frames: 0 (0.00%)
50th percentile: 4950ms
90th percentile: 4950ms
99th percentile: 4950ms
Number Missed Vsync: 0
게임은 멀쩡히 돌아가는 중인데 렌더링된 프레임이 0입니다. 4950ms라는 백분위수도 말이 안 되는 값입니다. 측정이 안 된 것이지 게임이 멈춘 게 아닙니다.
2. 왜 0인가
gfxinfo가 세는 것은 HWUI가 그린 프레임입니다. HWUI는 안드로이드가 버튼·목록·텍스트 같은 일반 앱 화면을 그리는 경로입니다.
그런데 언리얼 엔진이나 유니티로 만든 게임은 이 경로를 쓰지 않습니다. SurfaceView를 하나 띄워놓고 엔진이 직접 OpenGL·Vulkan으로 그립니다. HWUI 입장에서는 그린 게 아무것도 없으니 0이 맞습니다.
이 게임의 액티비티 이름만 봐도 알 수 있습니다.
adb shell dumpsys activity activities | findstr topResumedActivity
topResumedActivity=ActivityRecord{... com.com2us.es.android.google.kr.normal/com.epicgames.unreal.GameActivity}
com.epicgames.unreal.GameActivity — 언리얼 엔진입니다. 유니티라면 com.unity3d.player.UnityPlayerActivity가 보입니다. 이 이름이 보이면 gfxinfo는 포기하세요.
반대로 카카오톡이나 브라우저처럼 일반 UI로 만든 앱은 gfxinfo가 정상적으로 잡힙니다. 도구를 잘못 고른 것뿐입니다.
3. 실제로 되는 방법 — SurfaceFlinger timestats
SurfaceFlinger는 화면에 실제로 출력된 프레임을 관리하는 쪽이라, 게임이 어떤 엔진을 쓰든 상관없이 잡힙니다.
순서는 이렇습니다.
1) 초기화
adb shell dumpsys SurfaceFlinger --timestats -disable -clear
2) 측정 시작
adb shell dumpsys SurfaceFlinger --timestats -enable
3) 게임을 원하는 만큼 플레이 (60초 권장)
4) 결과 출력
adb shell dumpsys SurfaceFlinger --timestats -dump
5) 측정 종료 (반드시 꺼주세요)
adb shell dumpsys SurfaceFlinger --timestats -disable -clear
5번을 빼먹으면 계속 통계를 쌓습니다. 배터리와 성능에 조금씩 부담이 되니 측정이 끝나면 꼭 끄세요.
4. 결과 읽는 법
출력이 길게 나오는데, layerName에 게임 이름이 들어간 블록만 보면 됩니다.
layerName = SurfaceView[com.com2us.es.android.google.kr.normal/
com.epicgames.unreal.GameActivity]@0(BLAST)#166524
totalFrames = 892
droppedFrames = 0
averageFPS = 14.620
averageFPS가 우리가 찾던 값입니다. 이 기기에서 이 게임은 평균 14.62프레임으로 돌고 있었습니다.
바로 아래 히스토그램이 더 중요합니다. 프레임과 프레임 사이 간격을 밀리초 단위로 센 것입니다.
| 프레임 간격 | 횟수 | 환산 프레임 |
| 16ms | 27 | 60fps |
| 33ms | 90 | 30fps |
| 50ms | 200 | 20fps |
| 66ms | 244 | 15fps |
| 86ms | 191 | 약 12fps |
| 102ms | 97 | 약 10fps |
| 118ms | 36 | 약 8fps |
| 134ms | 7 | 약 7fps |
평균만 보면 14.6fps 하나지만, 실제로는 66ms(15fps) 근처에 가장 많이 몰려 있고 102ms 이상으로 늘어지는 구간도 140번 있었습니다. 이 늘어지는 구간이 눈에 보이는 버벅임입니다.
평균 프레임이 같아도 이 분포가 넓으면 훨씬 끊겨 보입니다. 평균보다 분포를 보세요.
5. 측정 환경
| 항목 | 값 |
| 기기 | 갤럭시 Z 플립4 (SM-F721N) |
| 안드로이드 | 14 (SDK 34) |
| 램 | 8GB (실사용 7.1GB) |
| 화면 주사율 | 60Hz (displayRefreshRate = 60 fps) |
| 게임 | 제우스: 오만의 신 12.60.0 (언리얼 엔진) |
| 측정 시간 | 60초 |
6. 자주 막히는 지점
출력이 통째로 안 나온다
제조사 커스텀 롬에서 timestats가 빠진 경우가 있습니다. 이때는 -enable 후 -dump가 빈 줄만 반환합니다. 방법이 없으니 게임 내 프레임 표시 기능을 쓰세요.
layerName 블록이 안 보인다
게임이 백그라운드로 내려가 있으면 안 잡힙니다. 게임을 화면에 띄운 상태로 측정하세요.
averageFPS가 화면 주사율보다 높게 나온다
정상입니다. 게임이 주사율보다 많이 그려도 실제 출력은 주사율에 맞춰 잘립니다. 체감은 주사율이 상한입니다.
여러 기기가 붙어 있어 명령이 안 먹는다
adb -s <기기ID> shell ... 로 대상을 지정하세요. 기기 ID는 adb devices에 나옵니다.
정리
- 일반 앱 프레임 → dumpsys gfxinfo
- 게임 프레임 → dumpsys SurfaceFlinger --timestats
- 액티비티 이름에 unreal이나 unity가 보이면 gfxinfo는 무조건 0입니다
측정 기준일: 2026년 9월 26일

'에뮬레이터·안드로이드 세팅' 카테고리의 다른 글
| 개발자 옵션 애니메이션 배율, 앱이 진짜 빨라질까 — 19회 실측 (0) | 2026.09.26 |
|---|