Разработка сред управляемого исполнения на примере виртуальной машины Java Занятие 3 Салищев С.И. Элементы модели данных Структура объекта Структура класса Стеки нитей Локальные данные нитей Требования подсистем Исполнитель Доступ к типу объекта во время исполнения Менеджер памяти Последовательное перечисление объектов Информационные биты в каждом объекте Планировщик Хранение состояния монитора Библиотеки Уникальный хеш код объекта Внешний интерфейс Память для стека внешнего вызова Все компоненты Доступ к локальным данным нити Память современного процессора запрос Виртуальная память Трансляция адреса Кэш промах Физическая память Чтение из L1 кэша – 3 такта Чтение из L2 кэша – 9 - 15 тактов Чтение из памяти – 30 - 180 тактов Требования производительности Прямой доступ к данным из скомпилированного кода Максимальная плотность упаковки Выравнивание полей Быстрая диспетчеризация виртуальных вызовов Быстрая проверка типов Быстрая синхронизация Быстрый доступ к локальным данным нити Эффективное использование стека нити Эффективная передача данных через внешний интерфейс Организация структур данных Косвенность (ссылки, списки) Неограниченный максимальный размер Потеря производительности Сложные структуры данных Выделение виртуальной памяти* Ограничение максимального размера Максимальная производительность Простая структура * практический выигрыш от 64 бит Упаковка адресов (bit stealing) Простой случай v = mask = y 0 align x 1…1 z 0 addr = base | (v & mask) Индексация addr = base + x * elemSize Пример: упаковка 64 битных ссылок objAddr64 = heapBase + objRef32 * 8 Адресуемое пространство – 32 GByte Объект и Класс class object objRef header TIB ref state TIB vtable itable class имеет структуру object TIB (Type Info Block) может не быть object отдельное пространство для TIB для улучшения кэширования и упаковки ссылок Заголовок может находиться не в начале объекта Упаковка полей (32 бита) с перестановкой class A { byte b; int i; Object r; long l; short s; } Header byte b byte gap0 short s int i ref r long l C struct 20 байт по порядку Header byte b byte gap0 short gap1 int i 24 ref r байта long l short s short gap2 сегрегированный ref r Header byte b byte gap0 short s int i long l Header byte b byte gap0 short gap1 int i ref r 32 int gap2 байта long l short s short gap3 int gap4 массив Header int length elem[] elems Хеш код объекта Предположения Уникальный хеш код используется редко Для неподвижного объекта адрес в памяти является уникальным хеш кодом GC может двигать объекты GC может добавить поле в заголовок при копировании 3 битное состояние хеш кода 0 – не запрашивался хеш код 1 – хеш код запрашивался, объект не перемещался 2 – объект перемещался, заголовок содержит дополнительное поле хеш кода Состояние монитора Предположения Любой объект может быть монитором Простое решение – в заголовке каждого объекта слово состояния монитора (обычно 24 бита) Дополнительные предположения Используется мало мониторов Эвристика, объект - монитор Экземпляр Object, Class Есть synchronized методы Была синхронизация по другим экземплярам класса Требуется обработка ошибки эвристики Решение – 1 бит в заголовке, наличие слова состояния монитора в заголовке В случае синхронизации при отсутствии слова состояния монитора в заголовке используется хеш таблица Структура заголовка объекта Стандартная реализация – 64 бита Ссылка на TIB - 32 бита Слово состояния монитора – 24 бита Состояние хеш кода – 3 бита Данные GC – 5 бит Упакованная реализация – 32 бита Ссылка на TIB - 24 бита Наличие слова состояния монитора – 1 бит Состояние хеш кода – 3 бита Данные GC – 4 бита Вызовы через интерфейс TIB ifaceId methodId ifaceId hashedMethId methodId TIB (vtable) method0 method1 method2 … Iface vmethId0 vmethId1 vmethId2 … iface0 method0 method1 … iface1 method0 method1 … iface2 method0 method1 … method0Impl iface0.meth1Impl dispatch1 iface1.meth1Impl method2Impl TIB (vtable) method0 method1 method2 … Реализация стека вызовов нити Релокация стека избыточное копирование памяти требует отдельного стека для вызова через внешний интерфейс Спагетти стек terminator frame 3 frame 2 frame 1 frame 0 terminator frame 6 frame 5 frame 4 entry сложность реализации требует отдельного стека для вызова через внешний интерфейс Выделение виртуальной памяти frame 8 frame 7 entry перерасход виртуальной памяти ограничение максимального размера стека Локальные данные нити (Thread Local Storage) Через системный вызов очень медленно только для нитей OS Через регистр процессора очень быстро занимает регистр процессора требует поддержки Исполнителя Часть стека нити быстро требует выделения стека блоками фиксированного размера с известным выравниванием Отображение блока стека медленно использование самосинхронизированной структуры данных