Call stack android studio

Native Memory Profiling with Android Studio 4.1

This is second in a two part series on What’s New in Profilers in Android Studio 4.1. Our previous post focused on What’s New in System Trace .

We’ve heard from those of you using C++ that debugging native memory can be fairly difficult, particularly in games. With Android Studio 4.1, we’ve implemented the ability to record call stacks of native memory allocations in our Memory Profiler. The native memory recording is built on top of the Perfetto backend, the next generation performance instrumentation and tracing solution for Android.

A common technique when trying to debug memory issues is to understand what is allocating memory and what is freeing memory. The rest of this article will walk you through how to use the Native Memory Profiler to help track down a leak, using the Gpu Emulation Stress Test as an example project.

Getting Started

When a memory leak is suspected, it’s often a good idea to start at a high level and watch for patterns in the system memory. To do this click the profile button in Android Studio, and enter the memory profiler for more detailed memory tracking information.

After running the simulation a few times we can see a few interesting patterns.

  1. The GPU memory increases as one may expect from a GPU emulation app, however it also looks like this memory gets properly cleaned up after the Activity is finished.
  2. The Native memory grows each time we enter the GpuEmulationStressTestActivity, however this memory does not seem to reset after each run, which might be indicative of a leak.

Native Memory Table View

Starting with Android Studio 4.1 Canary 6, we can grab a recording of native memory allocations to analyze why memory isn’t being released. To do this with the GPU emulation app, I stopped the running app and started profiling a fresh instance. Starting from a clean state, especially when looking at an unfamiliar codebase, can help narrow our focus. From the memory profiler I captured a native allocation recording throughout the duration of the GPU emulation demo. To do this restart the app by selecting Run-> Profile ‘app’. After the application starts and the profile window opens, click on the memory profiler and select “record native allocation”

The table view is useful for games/applications that use libraries implementing their own allocators highlighting malloc calls that are made outside of new.

When a recording is loaded, the data is first presented in a table. The table shows the leaf functions calling malloc. In addition to the function name, the table shows module, count, size, and delta. This information is sampled so it is possible not all malloc / free calls will be captured. This largely depends on the sampling rate, which will be discussed a bit later.

Читайте также:  Полная перезагрузка андроид самсунг а51

It is also useful to know where these functions that allocate memory are being called from. There are two ways to visualize this information. The first is by changing the “Arrange by allocation method” dropdown to “Arrange by call stack”. The table shows a tree of callstacks, similar to what you may expect from a CPU recording. If the current project has symbols (which is usually the case for debuggable builds; if you’re profiling an external APK check out the guide here) they will automatically be picked up and used. This allows you to right click on a function and “Jump to source”.

Memory Visualization (Native and non-native)

We’ve also added a new flame chart visualization to the memory profilers, allowing you to quickly see what callstacks are responsible for allocating the most memory. This is especially useful when a call stack is really deep.

There are four ways you can sort this data along the X axis:

  • “Allocation Size” is the default, showing the total amount of memory tracked.
  • “Allocation Count” shows the total number of objects allocated.
  • “Total Remaining Size” is the size of memory sampled throughout the capture that was not freed before the end of the capture.
  • “Total Remaining Count”, like the remaining size, is the count of objects captured but not freed before the end of the capture.

From here we can right click on the call stacks and select “Jump to Source” to take us to the line of code responsible for the allocation. However, taking a second glance at the visualization, we notice that the common parent, WorldState, is responsible for multiple leaks. To validate this, it can help to filter the results.

Filtering / Navigation

Like with the table view, the chart can be filtered using the filter bar. When the filter is used, the data in the chart is automatically updated to show only call stacks that have functions matching the word/regex searched.

70MB of our total assumed leak

Sometimes call stacks can get fairly long, or there just isn’t enough room to display the function name on screen. To assist with this, ctrl + mouse wheel will zoom in/out, or you can click on the chart to use W,A,S,D to navigate.

Verifying the findings

Adding a breakpoint and running the Emulation twice quickly reveals that on the second run we cause the leak by overwrite the pointer from our first run.

As a quick fix to the sample we can delete the world after it is marked done, profiling the application again to validate the fix.

Ending where we started by looking at the high level memory stats. Validating that deleting sWorld at the end of the simulation frees up the 70mb held by our first run.

Startup profiling and sample rate setting.

The sample above shows how native memory tracking can be used to find and fix memory leaks. Another common use for native memory tracking is understanding where memory is going during startup of the application. In Android Studio 4.1, we also added the ability to capture native memory recordings from the startup of the application. This is available in the “Run/Debug Configurations” dialog under the “Profiling” tab.

Читайте также:  Android mediaplayer with notification example

You can customize the sampling interval or record memory at startup in the Run configuration dialog.

Here you can also change the sampling rate for new captures. A smaller sampling rate can have a large impact on overall performance, while a larger sampling rate can miss some allocations. Different sampling rates work for different types of memory problems.

Wrapping up

With the new native memory profiler finding memory leaks and understanding where memory is being held on to just got a little bit easier. Give the native memory profiler a try in Android Studio 4.1, and leave any feedback on our bug tracker. For additional tips and tricks be sure to also check out our talk earlier this year at the Google for Games summit, Android memory tools and best practices.

Источник

Русские Блоги

Используйте стек вызовов для отладки кода Android

Поток кода Android более сложный, и легко потерять отслеживание кода, просто взглянув на код.Если вы можете добавить функцию стека вызовов в соответствующую позицию, мы можем выйти из потока вызовов кода Android в соответствии со стеком вызовов во время выполнения, что может вдвое увеличить результат с половиной усилий.

1, код Java

Метод добавления стека вызовов в коде Java очень прост, просто выведите исключение.

Обратите внимание, что Slog.i используется для печати информации в некоторых Java-файлах. Slog фактически инкапсулирует некоторые методы Log, но не инкапсулирует метод getStackTraceString.
Следовательно, при печати стека вызовов можно использовать только журнал, а не слог.

2. C ++ код

Это также проще в C ++

Добавьте приведенный выше код и вызовите функцию print_stack () напрямую.

3. C-код

В коде C нет функций, связанных со стеком вызовов, поэтому нам нужно использовать метод C ++.
Короче
1. Создайте новый файл cpp в соответствующем модуле test.cpp и скопируйте следующий код:

2. Добавьте соответствующий код в mk, чтобы его можно было скомпилировать в этот файл.

3. Добавить заявление в используемый файл

4. Прямое использование
Напишите printCallStack (), где вам нужно его использовать.

4. Код ядра

Другой

Для стека вызовов, напечатанного C / C ++, мы копируем информацию стека вызовов в файл, такой как 1.txt
и поместите его в код среды конфигурации, используйте стек 1.txt для преобразования информации стека вызовов в конкретный номер строки
Сценарий стека автоматически найдет информацию о символах в каталоге символов в соответствии с переменными среды, настроенными кодом Android.
автоматически вызывает arm-linux-androideabi-addr2line / aarch64-linux-android-addr2line в соответствии с таблицей символов для преобразования информации стека вызовов в конкретный номер строки, что может значительно повысить эффективность отладки.

Интеллектуальная рекомендация

Используйте шаблон состояния вместо if else

Большинство разработчиков все еще используютif elseСтруктура процесса, виделиjdonизbanqСтатья написана Большим Братом, используяcommand,aopЗамена шаблонаif elseСтруктура процесса. Я не совсем понял эт.

Проектирование архитектуры: схема проектирования уровня балансировки нагрузки (5) — установка одного узла LVS

1 Обзор Предыдущая статья «Проектирование архитектуры: проектирование уровня балансировки нагрузки (4) — Принципы LVS» (http://blog.csdn.net/yinwenjie/article/details/46845997), мы предста.

Рыба образования, средняя школа закончила в учебном класс, как найти первую работу.

Self-брат Я девять ноль, теперь занимается разработкой веб-конца Java. Некоторое понимание и восприятие учебных курсов. Учебное заведение является ямой, дорога, что вы уже прошли, только вы знаете, дл.

Синглтон паттерн в питоне

Дизайн шаблона Шаблон дизайна — это краткое изложение предыдущей работы, которое, как правило, широко распространено людьми и является зрелым решением конкретной проблемы. Он предназначен для многораз.

Java Counce Collection

TRUEEWAP основан на реализации красных навигаций. Это отображение отсортировано в соответствии с его природооформленным порядком или отсортировано в соответствии с компаратором, предусмотренным при со.

Читайте также:  Состояние батареи андроид команда

Вам также может понравиться

динамический прокси-сервер jdk (Proxy, InvocationHandler), включая исходный код $ Proxy0

1. Связанные классы и методы: java.lang.reflect.Proxy, Прокси предоставляет статические методы для создания динамических прокси-классов и экземпляров. newProxyInstance() Возвращает экземпляр прокси-кл.

Юля: Об изменениях в Array 1.0

Версии до 1.0, например 0.2-0.6, Но теперь 1.0 это сообщит об ошибке. Это использование претерпело серьезные изменения! такие как: Это можно считать серьезным изменением.

студия Android генерирует статическую библиотеку jni

Android Сяобай, который только что вошел в общество, описывает, как использовать студию Android для создания статической библиотеки jni. 1. Подготовка: Сначала установите ndk, сначала сами Baidu, позж.

Nginx 502 раствор

Общие решения Nginx 502 Bad Gateway следующие: Nginx 502 Ошибка 1: Количество сайтов велико, а количество PHP-CGI мало. Для этой 502 ошибки просто увеличивайте количество процессов PHP-CGI. В частност.

Java вызывает SMS-интерфейс WebService

1. Описание интерфейса WebService Отправьте в виде http-сообщения, выше — информация о запросе, а ниже — возвращаемое значение. Представлен раздел возвращаемого значения документа интерфейса. 2. Код J.

Источник

Что такое call stack?

Часть памяти компьютера отведена под стек.
Когда вы вызываете какую-либо функцию в вашем коде, параметры функции кладутся в стек (зачастую, но есть и другие способы). Так же необходимо знать, куда вернуться из функции — в стек кладётся адрес возврата.

Call Stack — окно, в котором отображаются все уровни вложенности вызовов функций.
Там вы можете узнать, в какой функции вы сейчас находитесь, из какой функции она была вызвана и так далее рекурсивно наверх вплоть до точки входа в программу.
Собственно call stack вычисляется на основе информации из стека.

Когда-то был оператор goto, и программы выглядели так

Мы что-то проверяем, если проверка успешна, вызываем какое-то действие. Затем возвращаемся назад.
Но такой вариант оказался неудобным, если это какое-то действие нужно вызывать из разных мест, а потом возвращаться именно в эти разные места. Поэтому сейчас используется не goto, а call (вызов), который кладет в стек адрес текущего места выполнения и переходит в подпрограмму. В конце подпрограммы по команде return, он берет из стека адрес и по нему возвращается назад.
Так как в стек можно положить что-то еще, то можно внутри вызванной подпрограммы вызвать другую подпрограмму, и рекурсивно вызывать столько раз сколько нужно. Потом все call-ы будут красиво закрыты return-ами в обратном порядке.

В данном варианте у нас работает так:
1. из основной части main, вызывается program1 (в стек кладется адрес этой)
2. из вызванного program1 вызывается program3 (в стек добавляется адрес этой команды, там уже две)
3. из program3 мы возвращаемся, беря последнее значение из стека (возвращаемся в program1)
4. снова возвращаемся, беря адрес из стека и попадаем в main
5. тоже самое с вызовом program2-program3-program2-main

Стек обычно растет сверху вниз, каждая команда return берет самый последний нижний адрес и возвращается по нему, что позволяет создавать множество вложенных вызовов, и рекурсивно с ними работать.
Но не нужно забывать, что стек не бесконечен. десять или сто вызовов вообще ни о чем на современных компах, но миллион или миллиард, умножить на размер адреса (например 4 байта), может занять мегабайты и гигабайты.

Чтобы при остановке выполнения (на точке останова или при выбросе исключения) узнать, в какой функции (и возможно с номером строчки кода) произошла остановка, со вложенностью.

Call stack trace of exception:

Английский не очень хорошо знаю,

Источник

Оцените статью