Как GC освобождает память
Фрагментация
Фрагментация
Фрагментация
Память процесса
Этапы
Маркировка
Маркировка
Маркировка Локальные переменные
Маркировка Локальные переменные
Маркировка Локальные переменные
Маркировка Локальные переменные
Маркировка Карточные столы
Маркировка Таблица Handle
Маркировка Корни финализаторов
Маркировка Корни финализаторов
Флаг маркировки
Флаг маркировки
Флаг маркировки
Sweep
Sweep
Compact
Compact
Compact
Brick table
Compact
Compact
Compact
Compact
Сафин Рустам
2.23M
Category: softwaresoftware

Как GC освобождает память

1. Как GC освобождает память

Сафин Рустам

2. Фрагментация

2

3. Фрагментация

3

4. Фрагментация

4

5. Память процесса

Thread stack
Gen2
Gen1
5

6. Этапы

GarbageCollectGeneration()
{
SuspendEE();
garbage_collect();
RestartEE();
}
garbage_collect()
{
generation_to_condemn();
gc1();
}
gc1()
{
mark_phase();
plan_phase();
}
plan_phase()
{
if (compact)
{
relocate_phase();
compact_phase();
}
else
make_sweep();
}
6

7. Маркировка

7

8. Маркировка

Корни
Стек локальных переменных
Таблица финализаторов
Таблица Handle
Карточные столы
8

9. Маркировка Локальные переменные

public static ExtensionConfig Read(string filename) {
var config = new ExtensionConfig();
if (!File.Exists(filename))
return config;
var doc = XDocument.Load(filename, LoadOptions.None);
var root = doc.Root;
if (root.Name == XML_ROOT_NAME)
Read(root, config);
return config;
}
9

10. Маркировка Локальные переменные

public static ExtensionConfig Read(string filename) {
var config = new ExtensionConfig();
if (!File.Exists(filename))
return config;
var doc = XDocument.Load(filename, LoadOptions.None);
var root = doc.Root;
if (root.Name == XML_ROOT_NAME)
Read(root, config);
return config;
}
//
//
//
//
//
//
//
//
config
config
config,
config,
config,
config,
config
doc
doc, root
root
root
10

11. Маркировка Локальные переменные

public static ExtensionConfig Read(string filename) {
var config = new ExtensionConfig();
if (!File.Exists(filename))
return config;
var doc = XDocument.Load(filename, LoadOptions.None);
var root = doc.Root;
if (root.Name == XML_ROOT_NAME)
Read(root, config);
//
//
//
//
//
//
//
config
config
config,
config,
config,
config,
doc
doc, root
root
root
fixed (IntPtr* ptr = this.accessor.DbBinding) {
// ..
}
// config, ptr
// config, ptr
// config
return config;
// config
}
11

12. Маркировка Локальные переменные

public static ExtensionConfig Read(string filename) {
var config = new ExtensionConfig();
if (!File.Exists(filename))
return config;
var doc = XDocument.Load(filename, LoadOptions.None);
var root = doc.Root;
if (root.Name == XML_ROOT_NAME)
Read(root, config);
//
//
//
//
//
//
//
rax
rax
rax,
rax,
rax,
rax,
rbx
rbx, rcx
rbx
rbx
fixed (IntPtr* ptr = this.accessor.DbBinding) {
// ..
}
// rax, rbx [pinned]
// rax, rbx [pinned]
// rax
return config;
// rax
}
12

13. Маркировка Карточные столы

13

14. Маркировка Таблица Handle

Global handle table map
buckets

STRONG
SOH
PINNED
LOH
14

15. Маркировка Корни финализаторов

public class Foo
{
public void DownloadFromUrl(string url)
{
using (var client = new HttpClient())
{
this.result = client.Get(url);
}
}
~Foo()
{
Console.WriteLine("In finalizer");
}
}
15

16. Маркировка Корни финализаторов

{
public void DownloadFromUrl(Foo this, string url)
{
using (var client = new HttpClient())
{
this.result = client.Get(url)
}
}
~Foo(Foo this)
{
Console.WriteLine("In finalizer");
}
}
16

17. Флаг маркировки

public class
{
public int
public int
public int
public int
}
SomeClass
Value1;
Value2;
Value3;
Value4;
17

18. Флаг маркировки

public class
{
public int
public int
public int
public int
}
SomeClass
Value1;
Value2;
Value3;
Value4;
18

19. Флаг маркировки

#ifdef _TARGET_64BIT_
#define OBJHEADER_SIZE
#else
#define OBJHEADER_SIZE
#endif
(sizeof(DWORD) + sizeof(DWORD))
sizeof(DWORD)
#define set_marked(obj) header(obj)->SetMarked()
BOOL gc_heap::gc_mark1 (uint8_t* obj)
{
BOOL marked = !marked (obj);
set_marked (o);
return marked;
}
void set_marked()
{
RawSetMethodTable(RawGetMethodTable()) | 0x1);
}
19

20. Sweep

20

21. Sweep

void sweep(Root* root) {
Object** object = &root->next;
while (*object) {
if (!(*object)->marked) {
/* Объект не маркирован, можем освободить память. */
Object* unreached = *object;
*object = unreached->next;
free(unreached);
} else {
/* Объект маркирован. Снимем отметку для следующего GC и перейдем к следующему. */
(*object)->marked = 0;
object = &(*object)->next;
}
}
}
21

22. Compact

22

23. Compact

gap
gap
plug
gap
plug
MT
H
MT
offset
-160B
H
MT
H
H
MT
H
MT
plug
size
64B
offset
-96B
MT
size
64B
offset
-32B
H
MT
H
size
32B
gap
23

24. Compact

gap
gap
plug
gap
plug
MT
H
MT
H
LR
relo
c
offset
-160B
gap
MT
H
MT
H
LR
relo
c
MT
H
MT
plug
size
64B
offset
-96B
gap
size
64B
offset
-32B
H
MT
H
size
32B
gap
24

25. Brick table

0x1000
0x2000
MT
H

MT
0x2f12
H
MT
0x16f1
H
MT
H
MT
H
MT

H
0x0

26. Compact

internal unsafe struct MyBuffer
{
public fixed char fixedBuffer[128];
}
fixed (char* charPtr = myBuffer.fixedBuffer)
{
*charPtr = 'A';
}
26

27. Compact

gap
gap
pinned
plug
size
64B
plug
gap
plug
MT
H
MT
H
LR
relo
c
offset
-160B
gap
MT
H
MT
offset
-96B
H
H
MT
plug
size
32B
MT
size
32B
offset
-32B
H
MT
H
size
32B
gap
27

28. Compact

gap
gap
pinned
plug
size
64B
plug
gap
plug
MT
H
MT
H
LR
relo
c
offset
-160B
gap
MT
H
MT
offset
-96B
H
H
MT
plug
size
32B
MT
size
32B
offset
-32B
H
MT
H
size
32B
gap
28

29. Compact

gap
gap
plug
pinned
plug
gap
plug
MT
H
MT
offset
-160B
H
MT
H
MT
H
H
MT
H
MT
plug
size
32B
size
32B
offset
-96B
MT
size
64B
offset
-32B
H
MT
H
size
32B
gap
29

30. Сафин Рустам

Разработчик
в г. Уфа
[email protected]
English     Русский Rules