DEV_EASY_NOTES Telegram 147
Медленно мы подходим к интересным и более хардкорным темам. ZygotеInit каждый видел в стэке вызов функций. Независимо от того, что у вас за приложение стартовать все будет отсюда.

Zygote это термин из биологии, клетка которая возникла при слиянии мужской и женской половых клеток. Zygote после определённого времени начинает делиться клонируя себя. Разработчики назвали этот класс не просто так, потому как в сущности это и происходит каждый раз при старте приложения.

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

В init.rc описано как стартовать все демоны, сервисы и остальные элементы системы. Этот же файл запускает AndroidRuntime. В С++ коде он кстати так и называется AndroidRuntime. Этот самый AndroidRuntime в свою очередь запускает JVM и в частности main функцию нашего ZygotеInit.

Что происходит в ZygotInit.main? Для начала подгружаются все классы для работы этой самой JVM и все все Android зависимости необходимые для работы. Если интереснее подробнее разобраться в том, как работают ClassLoader у меня и на это есть серия постов. После загрузки всех необходимых классов, запускается некий ZygoteServer. Этот ZygoteServer запускает бесконечный цикл и чего-то ждет.

Вот тут начинается самое интересное. Эта та магия системного программирования которую практически никогда не увидишь в обычных проектах. Для объяснения нужно написать немного кода на низкоуровневом языке. C++ я жутко не люблю и мне кажется от должен уже отправится на полку истории, поэтому мы черканем пару строк на Rust. Не волнуйтесь сложно не будет, я профессионал. Пример вот такой:

unsafe { // unsafe просто позволяет запускать небезопасные штуки
let fork_result = libc::fork(); //вот тут происходит магия
match fork_result {
-1 => println!("Ошибка при попытке сделать fork"),
0 => println!("Бонжур мы в child процессе, pid {}”, libc::getpid()),
_ => {
println!("Тут мы в изначальном процессе, pid {}", libc::getpid());
}
}
}


Сейчас нужно будет на максимум включить абстрактное мышление. Значит есть в Unix такой системный вызов, который называется fork. Все что он делает, копирует процесс и запускает его как отдельный. Еще раз вдумайтесь! Этот системный вызов берет вашу прогу, копирует все состояния переменных, все потоки, все стэки, весь хип все это дело переносит в отдельное место в оперативной памяти и запускает как отдельный процесс.

Забавная вещь в том, что можно легко и просто вызвать этот системный вызов (да вызывать вызов) из любой точки программы. Порой трудно в потоках разобраться, а можно сделать прогу, где у тебя после определенного вызова функции вообще другой процесс будет. Именно это и делает ZygotInit.

ZygotInit запускает ZygoteServer, который просто ждет команду от системы на запуск нового процесса. ZygoteServer запускает бесконечный цикл и вот тут интересно. Когда система дает команду на создание нового процесса, этот новый процесс выходит из этого бесконечного цикла и идет дальше запуская ActivityThread и т.д. Изначальный же процесс так и остается в бесконечном цикле в ожидании новых команд от ОС.

Все скорее всего слышали, что когда стартует приложение, у нас создается копия JVM. Мало кто объясняет как именно создается и зачем копия? Как это происходит мы уже разобрали, остался вопрос зачем? Все просто, Android и так не всегда быстрый, а если бы при каждом старте еще и нужно было каждый раз подгружать все нужные классы было бы вообще грустно. Поэтому разработчики придумали тупо копировать инстанс JVM с уже загруженными классами.

Ну а что там происходит с процессом, который вышел из этого бесконечного цикла мы разберем в следующих постах.
👍24🔥62



tgoop.com/dev_easy_notes/147
Create:
Last Update:

Медленно мы подходим к интересным и более хардкорным темам. ZygotеInit каждый видел в стэке вызов функций. Независимо от того, что у вас за приложение стартовать все будет отсюда.

Zygote это термин из биологии, клетка которая возникла при слиянии мужской и женской половых клеток. Zygote после определённого времени начинает делиться клонируя себя. Разработчики назвали этот класс не просто так, потому как в сущности это и происходит каждый раз при старте приложения.

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

В init.rc описано как стартовать все демоны, сервисы и остальные элементы системы. Этот же файл запускает AndroidRuntime. В С++ коде он кстати так и называется AndroidRuntime. Этот самый AndroidRuntime в свою очередь запускает JVM и в частности main функцию нашего ZygotеInit.

Что происходит в ZygotInit.main? Для начала подгружаются все классы для работы этой самой JVM и все все Android зависимости необходимые для работы. Если интереснее подробнее разобраться в том, как работают ClassLoader у меня и на это есть серия постов. После загрузки всех необходимых классов, запускается некий ZygoteServer. Этот ZygoteServer запускает бесконечный цикл и чего-то ждет.

Вот тут начинается самое интересное. Эта та магия системного программирования которую практически никогда не увидишь в обычных проектах. Для объяснения нужно написать немного кода на низкоуровневом языке. C++ я жутко не люблю и мне кажется от должен уже отправится на полку истории, поэтому мы черканем пару строк на Rust. Не волнуйтесь сложно не будет, я профессионал. Пример вот такой:

unsafe { // unsafe просто позволяет запускать небезопасные штуки
let fork_result = libc::fork(); //вот тут происходит магия
match fork_result {
-1 => println!("Ошибка при попытке сделать fork"),
0 => println!("Бонжур мы в child процессе, pid {}”, libc::getpid()),
_ => {
println!("Тут мы в изначальном процессе, pid {}", libc::getpid());
}
}
}


Сейчас нужно будет на максимум включить абстрактное мышление. Значит есть в Unix такой системный вызов, который называется fork. Все что он делает, копирует процесс и запускает его как отдельный. Еще раз вдумайтесь! Этот системный вызов берет вашу прогу, копирует все состояния переменных, все потоки, все стэки, весь хип все это дело переносит в отдельное место в оперативной памяти и запускает как отдельный процесс.

Забавная вещь в том, что можно легко и просто вызвать этот системный вызов (да вызывать вызов) из любой точки программы. Порой трудно в потоках разобраться, а можно сделать прогу, где у тебя после определенного вызова функции вообще другой процесс будет. Именно это и делает ZygotInit.

ZygotInit запускает ZygoteServer, который просто ждет команду от системы на запуск нового процесса. ZygoteServer запускает бесконечный цикл и вот тут интересно. Когда система дает команду на создание нового процесса, этот новый процесс выходит из этого бесконечного цикла и идет дальше запуская ActivityThread и т.д. Изначальный же процесс так и остается в бесконечном цикле в ожидании новых команд от ОС.

Все скорее всего слышали, что когда стартует приложение, у нас создается копия JVM. Мало кто объясняет как именно создается и зачем копия? Как это происходит мы уже разобрали, остался вопрос зачем? Все просто, Android и так не всегда быстрый, а если бы при каждом старте еще и нужно было каждый раз подгружать все нужные классы было бы вообще грустно. Поэтому разработчики придумали тупо копировать инстанс JVM с уже загруженными классами.

Ну а что там происходит с процессом, который вышел из этого бесконечного цикла мы разберем в следующих постах.

BY Dev Easy Notes


Share with your friend now:
tgoop.com/dev_easy_notes/147

View MORE
Open in Telegram


Telegram News

Date: |

To upload a logo, click the Menu icon and select “Manage Channel.” In a new window, hit the Camera icon. You can invite up to 200 people from your contacts to join your channel as the next step. Select the users you want to add and click “Invite.” You can skip this step altogether. Users are more open to new information on workdays rather than weekends. During a meeting with the president of the Supreme Electoral Court (TSE) on June 6, Telegram's Vice President Ilya Perekopsky announced the initiatives. According to the executive, Brazil is the first country in the world where Telegram is introducing the features, which could be expanded to other countries facing threats to democracy through the dissemination of false content. ‘Ban’ on Telegram
from us


Telegram Dev Easy Notes
FROM American