Kiểm tra dấu vết

Chế độ xem dấu vết trong Trình phân tích CPU cung cấp một số cách để xem thông tin từ các dấu vết được ghi lại.

Đối với dấu vết phương thức và dấu vết hàm, bạn có thể xem Call Chart (Biểu đồ lệnh gọi) ngay trong tiến trình Threads (Luồng) cũng như trong các thẻ Flame Chart (Biểu đồ hình ngọn lửa), Top Down (Từ trên xuống), Bottom Up (Từ dưới lên) và Events (Sự kiện) trong ngăn Analysis (Phân tích). Đối với các khung ngăn xếp lệnh gọi, bạn có thể xem phần mã đã được thực thi và lý do gọi mã đó. Đối với dấu vết hệ thống, bạn có thể xem Trace Events (Sự kiện theo dõi) ngay trong tiến trình Threads (Luồng) cũng như trong các thẻ Flame Chart (Biểu đồ hình ngọn lửa), Top Down (Từ trên xuống), Bottom Up (Từ dưới lên) và Events (Sự kiện) trong ngăn Analysis (Phân tích).

Bạn có thể sử dụng chuột và phím tắt hiện có để di chuyển dễ dàng hơn trong Call Charts (Biểu đồ lệnh gọi) hoặc Trace Events (Sự kiện theo dõi).

Kiểm tra dấu vết bằng Biểu đồ lệnh gọi

Biểu đồ lệnh gọi cung cấp biểu đồ minh hoạ cho dấu vết phương thức hoặc dấu vết hàm, trong đó trục hoành biểu thị thời gian và thời điểm thực hiện lệnh gọi, còn trục tung thể hiện các hàm được gọi. Lệnh gọi đến API trên hệ thống sẽ có màu cam, các lệnh gọi đến phương thức riêng của ứng dụng được hiển thị bằng màu xanh lá cây và lệnh gọi đến các API của bên thứ ba (bao gồm cả API trong ngôn ngữ Java) sẽ có màu xanh lam. Hình 4 mô tả một ví dụ về biểu đồ lệnh gọi và minh hoạ khái niệm thời gian tự thực thi (self time), thời gian thực thi hàm được gọi (children time) và tổng thời gian thực thi (total time) cho một phương thức hoặc hàm xác định. Bạn có thể tìm hiểu thêm về các khái niệm này trong hướng dẫn kiểm tra dấu vết bằng phương pháp Từ trên xuống và Từ dưới lên.

Hình 1. Một ví dụ minh hoạ cho biểu đồ lệnh gọi về thời gian tự thực thi, thời gian thực thi các hàm được gọi và tổng thời gian thực thi của phương thức D.

Mẹo: Để chuyển mã nguồn của phương thức hoặc hàm, hãy nhấp chuột phải rồi chọn Jump to Source (Chuyển đến Nguồn). Bạn có thể thực hiện thao tác này từ bất kỳ thẻ nào trong ngăn Analysis (Bản phân tích).

Kiểm tra dấu vết bằng thẻ Biểu đồ hình ngọn lửa

Thẻ biểu đồ hình ngọn lửa cung cấp biểu đồ lệnh gọi suy ngược để tổng hợp các ngăn xếp lệnh gọi giống nhau. Tức là các phương thức hoặc hàm giống nhau có cùng trình tự phương thức gọi, được thu thập và thể hiện dưới dạng một thanh dài trong biểu đồ ngọn lửa (thay vì hiển thị dưới dạng nhiều thanh ngắn hơn, như minh hoạ trong biểu đồ lệnh gọi). Điều này giúp bạn dễ dàng nhận biết phương thức hoặc hàm nào đang tiêu thụ nhiều thời gian nhất. Tuy nhiên, điều này cũng có nghĩa là trục hoành trên biểu đồ không biểu thị tiến trình; thay vào đó, nó cho biết thời gian tương đối mà mỗi phương thức hoặc hàm cần để thực thi.

Để giúp minh họa khái niệm này, hãy xem xét Biểu đồ lệnh gọi trong Hình 2. Xin lưu ý rằng phương thức D thực hiện nhiều lệnh gọi đến phương thức B (B1, B2 và B3) và một số trong số các lệnh gọi đến B đó sẽ thực hiện lệnh gọi đến phương thức C (C1 và C3).

Hình 2. Biểu đồ lệnh gọi với nhiều lệnh gọi phương thức cùng chia sẻ một trình tự phương thức gọi chung.

Vì B1, B2 và B3 có cùng một trình tự phương thức gọi (A → D → B) nên các phương thức này được gộp chung lại, như trong Hình 3. Tương tự, hệ thống gộp C1 và C3 vì chúng có cùng trình tự phương thức gọi (A → D → B → C); lưu ý rằng phương thức C2 không được gộp chung lại bởi trình tự phương thức gọi có sự khác biệt (A → D → C).

Hình 3. Tổng hợp các phương thức giống nhau có chung một ngăn xếp lệnh gọi.

Các lệnh gọi tổng hợp được dùng để tạo biểu đồ hình ngọn lửa, như trong Hình 4. Lưu ý rằng đối với bất kỳ lệnh gọi xác định nào trong biểu đồ ngọn lửa, các lệnh gọi chiếm dụng nhiều thời gian CPU nhất sẽ biểu diễn trước.

Hình 4. Hình 5 minh hoạ cho biểu đồ hình ngọn lửa biểu diễn Biểu đồ lệnh gọi.

Kiểm tra dấu vết bằng phương pháp từ trên xuống dưới

Thẻ Từ trên xuống hiển thị một danh sách các lệnh gọi để mở rộng một phương thức hoặc một nút hàm hiển thị hàm được gọi. Hình 5 minh hoạ một cây đồ thị từ trên xuống biểu diễn biểu đồ lệnh gọi tại Hình 1. Mỗi mũi tên trong biểu đồ trỏ từ một lệnh gọi đến hàm được gọi.

Như minh hoạ trong Hình 5, việc mở rộng nút cho phương thức A trong thẻ Top Down (Từ trên xuống) sẽ cho thấy các hàm được gọi, phương thức B và phương thức D. Sau đó, việc mở rộng nút cho phương thức D sẽ tiết lộ các hàm phương thức đó gọi, phương thức B và phương thức C, v.v. Tương tự như thẻ Flame chart (Biểu đồ hình ngọn lửa), cây đồ thị từ trên xuống sẽ tổng hợp thông tin theo dõi cho các phương thức giống nhau có cùng một ngăn xếp lệnh gọi. Tức là thẻ Flame chart (Biểu đồ hình ngọn lửa) cung cấp biểu đồ minh hoạ cho thẻ Top down (Từ trên xuống).

Thẻ Top Down (Từ trên xuống) cung cấp các thông tin dưới đây giúp mô tả thời gian chiếm dụng CPU của mỗi lệnh gọi (thời gian cũng được biểu thị dưới dạng phần trăm trên tổng thời gian luồng chạy trong phạm vi xác định):

  • Self (Thời gian tự thực thi): thời gian mà phương thức hoặc lệnh gọi hàm thực thi mã của chính hàm hay phương thức đó, không phải thời gian thực thi của hàm được gọi như minh họa trong Hình 1 cho phương thức D.
  • Children (Thời gian hàm được gọi thực thi): thời gian phương thức hoặc lệnh gọi hàm thực thi hàm được gọi mà không phải mã của chính phương thức hoặc lệnh gọi hàm đó, như minh họa trong Hình 1 cho phương thức D.
  • Total (Tổng thời gian thực thi): tổng thời gian Self (Tự thực thi) và Children (Thực thi hàm được gọi) của phương pháp. Giá trị này thể hiện tổng thời gian ứng dụng thực thi một lệnh gọi, như minh họa trong Hình 1 cho phương thức D.

Hình 5. Cây đồ thị từ trên xuống.

Hình 6. Cây đồ thị từ dưới lên cho phương thức C dựa theo Hình 5.

Thẻ Bottom Up (Từ dưới lên) hiển thị danh sách các lệnh gọi trong đó khi mở rộng của một hàm hoặc nút của phương thức sẽ hiển thị phương thức gọi. Sử dụng dấu vết mẫu như minh hoạ trong Hình 5, hình 6 cung cấp cây đồ thị từ dưới lên cho phương thức C. Việc mở rộng nút cho phương thức C ở cây đồ thị từ dưới lên sẽ hiển thị từng phương thức gọi riêng, phương thức B và phương thức D. Xin lưu ý rằng, mặc dù phương thức B gọi phương thức C hai lần, nhưng phương thức B chỉ xuất hiện một lần khi mở rộng nút cho phương thức C ở cây đồ thị từ dưới lên. Sau đó, việc mở rộng nút cho phương thức B sẽ hiển thị phương thức gọi tới, phương thức A và phương thức D.

Thẻ Bottom Up (Từ dưới lên) sẽ hữu ích trong việc sắp xếp các phương thức hoặc hàm theo thời gian chiếm dụng nhiều nhất (hoặc ít nhất) của CPU. Bạn có thể kiểm tra từng nút với mục đích xác định phương thức gọi nào chiếm dụng nhiều thời gian CPU nhất để thực thi các phương thức hoặc hàm đó. So với cây đồ thị từ trên xuống, thông tin về thời gian của mỗi phương thức hoặc hàm trong cây đồ thị từ dưới lên tham chiếu đến phương thức ở đỉnh mỗi cây (nút trên cùng). Thời gian của CPU cũng được biểu diễn dưới dạng phần trăm trên tổng thời gian của luồng trong quá trình ghi. Bảng dưới đây diễn giải thông tin cho nút trên cùng và phương thức gọi (nút nhánh).

Thời gian tự thực thi Thời gian thực thi các hàm được gọi Tổng
Phương thức hoặc hàm ở đỉnh cây đồ thị từ dưới lên (nút trên cùng) Biểu diễn tổng thời gian mà phương thức hoặc hàm dùng để tự thực thi, không phải thời gian thực thi các hàm được gọi. So với cây đồ thị từ trên xuống, thông tin thời gian của phương pháp duyệt cây này thể hiện tổng thời gian mà tất cả các lệnh gọi đến phương thức hoặc hàm này trong thời gian ghi. Biểu thị tổng thời gian mà phương thức hoặc hàm dùng để thực thi hàm được gọi, không phải thời gian tự thực thi chính hàm hay phương thức đó. So với cây đồ thị từ trên xuống, thông tin thời gian của phương pháp duyệt cây này thể hiện tổng thời gian mà tất cả các lệnh gọi đến phương thức hoặc hàm của hàm được gọi tới trong thời gian ghi. Tổng thời gian tự thực thi và thời gian thực thi của hàm được gọi.
Phương thức gọi (nút nhánh) Biểu thị tổng thời gian tự thực thi của hàm được gọi trong lúc phương thức gọi tới. Như minh hoạ trong cây đồ thị từ dưới lên ở Hình 6, thời gian tự thực thi của phương thức B sẽ bằng tổng thời gian tự thực thi trong mỗi lần thực thi phương thức C khi được phương thức B gọi. Biểu thị tổng thời gian thực thi của hàm được gọi trong lúc phương thức gọi gọi tới. Như minh hoạ trong cây đồ thị từ dưới lên ở Hình 6, thời gian thực thi của hàm được gọi đến của phương thức B sẽ bằng tổng thời gian thực thi mỗi lần thực thi phương thức C khi được phương thức B gọi. Tổng thời gian tự thực thi và thời gian thực thi của hàm được gọi.

Lưu ý: Đối với một bản ghi cụ thể, Android Studio sẽ ngừng thu thập dữ liệu mới khi trình phân tích tài nguyên đạt đến giới hạn kích thước tệp (tuy nhiên, điều này sẽ không dừng quá trình ghi). Quy trình truy vết này thường thực hiện nhanh hơn nhiều so với truy vết đo lường bởi khi so sánh trên cùng một mẫu dấu vết, loại truy vết này thu thập nhiều dữ liệu hơn và hoàn thành trong khoảng thời gian ngắn hơn. Nếu bạn kéo dài thời gian kiểm tra tới thời điểm chế độ ghi đạt giới hạn, dữ liệu thời gian trong bảng theo dõi sẽ không thay đổi (vì không có dữ liệu mới). Thêm vào đó, nếu bạn chỉ chọn phần bản ghi không có dữ liệu, ngăn theo dõi sẽ hiển thị Mạng nhận biết thiết bị lân cận (NaN) đối với thông tin về thời gian.

Kiểm tra dấu vết bằng bảng Events (Sự kiện)

Bảng Events (Sự kiện) liệt kê tất cả lệnh gọi trong luồng đang được chỉ định. Bạn có thể sắp xếp các sự kiện đó bằng cách nhấp vào tiêu đề cột. Bằng cách chọn một hàng trong bảng, bạn có thể điều hướng thời điểm tiến trình của một cuộc gọi xác định bắt đầu và kết thúc. Việc này cho phép bạn xác định chính xác các sự kiện trên dòng thời gian.

Hình 7. Xem thẻ Sự kiện trong ngăn Phân tích.

Kiểm tra khung ngăn xếp lệnh gọi

Các ngăn xếp lệnh gọi rất hữu ích trong việc giúp bạn nắm rõ được phần nào của mã đã được thực thi và lý do lệnh đó được gọi. Nếu Callstack Sample Recording (Bản ghi mẫu ngăn xếp lệnh gọi) được thu thập cho chương trình Java/Kotlin thì ngăn xếp lệnh gọi đó thường sẽ không chỉ bao gồm mã Java/Kotlin mà còn bao gồm các khung từ mã gốc JNI, máy ảo Java (ví dụ như android::AndroidRuntime::start) và nhân hệ thống ([kernel.kallsyms]+offset). Điều này xảy ra do chương trình Java/Kotlin thường thực thi thông qua một máy ảo Java. Chương trình cần có mã gốc để chạy và giao tiếp với phần cứng cũng như với hệ thống. Trình phân tích tài nguyên biểu diễn những khung này để đảm bảo độ chính xác; tuy nhiên, tuỳ thuộc vào quy trình điều tra, bạn có thể thấy hoặc không thấy các khung cuộc gọi bổ sung này hữu ích. Trình phân tích tài nguyên cung cấp tính năng thu gọn những khung bạn không quan tâm đến, giúp bạn ẩn đi thông tin không liên quan đến quy trình điều tra.

Như ví dụ dưới đây, các dấu vết có nhiều khung được gắn nhãn[kernel.kallsyms]+offset, không hữu ích cho quá trình phát triển hiện tại.

Ví dụ về dấu vết lệnh gọi

Để gộp các khung này thành một, bạn sẽ chọn nút Collapse frames (Thu gọn khung) trên thanh công cụ, chọn đường dẫn để thu gọn và chọn nút Apply (Áp dụng) để áp dụng các thay đổi của bạn. Như trong ví dụ này, đường dẫn cần thu gọn là [kernel.kallsyms].

Ví dụ về trình đơn Simpleperf

Thao tác này sẽ thu gọn các khung hình tương ứng với đường dẫn đã chọn trên cả bên trái và bên phải bảng điều khiển, như hình minh hoạ bên dưới.

Ví dụ về khung thu gọn của Simpleperf

Kiểm tra dấu vết trên hệ thống

Khi kiểm tra một dấu vết trên hệ thống, bạn có thể kiểm tra Trace Events (Sự kiện theo dõi) dựa trên trạng thái của Threads (Luồng) để xem chi tiết về các sự kiện xảy ra trong từng luồng. Di chuột vào một sự kiện để xem tên của sự kiện và thời gian mỗi trạng thái chiếm dụng. Nhấp vào một sự kiện để xem thêm thông tin trong ngăn Analysis (Bản phân tích).

Kiểm tra dấu vết trên hệ thống: lõi CPU

Bên cạnh việc điều phối dữ liệu cho CPU, dấu vết hệ thống còn theo dõi tốc độ xung nhịp của lõi CPU. Điều này cho biết số lượng hoạt động trên mỗi lõi và xác định lõi đang theo dõi là lõi "chính" hay lõi "phụ" trong các bộ xử lý trên thiết bị di động hiện nay.

Hình 8. Xem hoạt động của CPU và sự kiện theo dõi cho Luồng kết xuất.

Ngăn CPU Cores (Các lõi CPU) (như trong Hình 8) cho thấy hoạt động của các luồng được điều phối trên mọi lõi. Di con trỏ chuột vào một hoạt động luồng để xem lõi này đang chạy trên Luồng nào tại một thời điểm xác định nào đó.

Để biết thêm thông tin về quy trình kiểm tra thông tin theo dõi trên hệ thống, hãy xem mục Điều tra vấn đề về hiệu suất của giao diện người dùng trong mục tài liệu systrace.

Kiểm tra dấu vết trên hệ thống: Tiến trình kết xuất khung

Bạn có thể kiểm tra thời gian để ứng dụng của bạn kết xuất từng khung trên Luồng chính và RenderThread để điều tra các nút thắt cổ chai khiến giao diện người dùng bị giật và tốc độ khung hình thấp. Để tìm hiểu cách sử dụng tính năng theo dõi trên hệ thống để điều tra và giúp giao diện người dùng bớt giật, hãy xem phần Phát hiện giao diện người dùng bị giật.

Kiểm tra dấu vết hệ thống: Xử lý bộ nhớ (RSS)

Đối với các ứng dụng được triển khai cho các thiết bị chạy Android 9 trở lên, phần Bộ nhớ xử lý (RSS) sẽ hiển thị dung lượng bộ nhớ vật lý mà ứng dụng đang sử dụng.

Hình 9. Xem dung lượng bộ nhớ vật lý trong trình phân tích tài nguyên.

Total (Tổng)

Đây là tổng dung lượng bộ nhớ vật lý mà quy trình xử lý đang sử dụng. Trên các hệ thống nhân Unix, tổng dung lượng còn được gọi là "Kích thước cài đặt thường trú", là sự kết hợp của vùng nhớ cấp phát ẩn danh, ánh xạ tệp và cấp phát vùng nhớ chia sẻ.

Đối với các nhà phát triển Windows, Kích thước cài đặt thường trú tương tự như Kích thước bộ nhớ cho tiến trình.

Allocated (Cấp phát)

Bộ đếm này sẽ theo dõi dung lượng bộ nhớ vật lý trung bình được cấp phát cho tiến trình nào đó. Bộ nhớ sẽ được cấp phát ẩn danh (không được lưu trong một tệp cụ thể) và ở chế độ riêng tư (không được chia sẻ). Trong hầu hết các ứng dụng, cách thức cấp phát này tạo thành bởi quá trình cấp phát vùng nhớ kiểu xếp đống - heap allocations (với malloc hoặc new) và vùng nhớ kiểu ngăn xếp - stack memory. Các vùng nhớ được cấp phát này sẽ được ghi vào tệp hoán đổi hệ thống (swap file) khi bị hoán đổi ra khỏi bộ nhớ vật lý.

File Mappings (Ánh xạ tệp)

Bộ đếm này sẽ theo dõi dung lượng bộ nhớ vật lý mà tiến trình nào đó đang sử dụng cho ánh xạ tệp – tức là trình quản lý bộ nhớ sẽ ánh xạ bộ nhớ từ các tệp vào một vùng nhớ xác định .

Shared (Dùng chung)

Bộ đếm này theo dõi dung lượng mà bộ nhớ vật lý đang dùng chung giữa nhiều tiến trình trong hệ thống.