Memory Management
Taşkaya, Batuhan
Learn what is going on behind the scene about memory. How CPython allocates memory? How it manages Private Heap? Does it uses abstractions for managing the memory? Does python relase memory back to the system? Learn how python GC works, reference counting and generational GC. How generations classified? How does reference counting mechanism work? This talk is going to try to answer all this questions. Motivation about that subject. Why do i need to know this stuff? What is the effect of these things on my code quality? Is that lecture enough for being a master about this subject? Understanding Objects Everything is an object in python (even code). If we want to understand what is going on behind the scene about memory allocation for objects first we should understand objects. This part has a cpython code reference for PyObject. We are going to learn python objects with seeing how they implemented. Memory Management Model Python has a great system about managing the memory (the private heap). Heap managed by +1th layer but the main part of this talk is +2th layer, object allocation. We'll discuss them Small Object Threshold Classifies objects into 2 sections. If size of an object bigger than 512 it is big else it is small. Abstractions We'll talk about abstractions, Arena ❯ Pool ❯ Block Deallocations We'll talk about GC, reference count, counting mechanism, generational gc, mark & sweep, generations.
 Hello everyone, my name is Batuan. I'm a student from Turkey. In this session we are going to talk about C Python's memory management. C Python is the major implementation of Python language and there are other implementations like PyPy with their own memory management. There are implementations like Jyton and Iron Python. They use their written language memory management. For example, Jyton use JVM's memory management. This talk contains a lot of implementation details so you can most of find stuff in docs. Why should you learn memory management concepts? It will show you behind the curtain. For an example, you may think why Python doesn't release memory back to the system or how it finds and detects side of references. All of them has an answer in behind the curtain. You are going to learn how to control it. Python has an interface for all internal things like abstraction texture they mentioned, parser, and it has an interface for garbage collector. You can control it. There are helper functions like sys.getref count. You can learn stuff of an object in memory. Although it seems unnecessary to learn them, Instagram increased their performance by 10% with disabling or enabling QC whenever they need. You are going to handle memory links, find them, and trace them into source with understanding of memory management. All locations of memory, memory management, we can examine memory management in two sections, allocation and allocation. Before we start, don't forget everything is an object in Python. In that memory, everything can be objects. Every Python object has two common fields. One is reference count and the other one is object itself. Reference count is the count of total reference made to that object. If you set A to 10 and B to 10, you will increase 10's reference count by 2. If you delete or set A and B to another object, you will decrease reference count by 2. If an object's reference count reaches 0, it will immediately be allocated. But there are some cases like object reference itself and it could not be deducted by reference count manager. So there is a GC. There are type pointers. It points object itself. It contains value of object, type of object, name of object, every attribute of object. It is memory management module of C Python. In the top layer, layer 3, there is Python objects and some of internal stuff. In the layer 2, there is Python's object allocator. It abstracts memory and manages objects. In the layer 1, there is Python's raw memory allocator. It ensures there is enough space in heap. If not, it requests memory from layer 0. Layer 0 is a system allocator. If you didn't change anything and using a standard Linux distribution, it might be malloc. And in bottom layers, there are physical and low things we are not talking about. Python divides objects into sections. If an object is bigger than a small object threshold, it is called as big. If not, it is called as small. Small object threshold is a static constant that defined in malloc.c in C Python repository. It is 512 bytes by default. Big objects, it is not one of our concerns. Python direct routes big objects to a system allocator with a set of verpes. Small objects, they manage it by layer 2 with three levels of obstructions. The first one is blocks. They encapsulate Python objects and pools and comps. They have the same size blocks and their size is 4 kilobytes, same as a virtual memory page. And there are arenas. They contain 64 pools. Blocks, first level of obstructions. The size of block determined with 8 bytes alignment notation. For an example, you have 30 bytes sized object. It will be put to the 32 bytes sized block. And whenever your object is downlocated, Python can put another object in a range of 25 to 32, to that same block. It brings optimization. And there are size IDX value. It has pools to contain same size blocks. Implementation of blocks, they design for containing Python objects. They use 8 byte alignment notation for better management of free blocks. And they mark this free and link to free blocks list of their pools when their object is downlocated. Pools, they encapsulate same size blocks. Their size is 4 kilobytes. Every pool has a pool header over it. It contains a list of free blocks. Next time, previous pools, the arena index of memory, the size IDX of blocks inside and some memory stuff. Pool says free blocks list. The list contains free blocks. And whenever a block free, it inserts that list. There are states of blocks. Use it means it's neither empty nor full. At this one block is free and at this one block is currently used. The full means there is no currently available blocks. And the empty means every block is empty. And it will be linked to free pools list of its arena. Arenas, they encapsulate pools. There's an overhead pool and they are double linked lists with next arena, previous pools. Their size is 256 kilobytes. Stim allocator only allocates space for arenas. And the other abstractions use space for arena space. And Python only releases memory back to the system when all pools is empty in that arena. Object specific. There are some object specific cases that's related with memory management. For example, string attorney. Python strings are immutable seconds of unicode. So Python can reference same string twice instead of creating any string in every operation. We call it string interning. If a string is simple, it will be interred and doesn't create twice. Simple strings are escalators, digits and underscores. For example, what one is a simple string. And this happens in compile time, so function calls and constructors doesn't affect that. And there is small integers. It's optimization for C Python. Python preallocates integers between negative 5 to 256. There are internal references to integers and it brings optimizations. There is garbage collection. Before we start talking about garbage collection, don't forget Python has not variables. It has names instead. And difference between names and variables only points to an object that lives in heap. Variables contain objects value. Reference is the pointer to that object that lives in heap. And reference count, as I mentioned, the total reference is made to that object. There's good size and best size of reference counting. It's easy to find unused objects and it doesn't require a marking time like in Mark S. Swip. But there are bad sites. Every Python object contains a reference count field and it costs object over it. It doesn't support for cyclic references. And it is one of the reasons of Jill. If Jill doesn't exist and two threads tries to increase an object's n values reference count, it will cause memory leaks. And that will be bad. And there is generational GC for cyclic references. Python runs this GC periodically. It uses an algorithm called Mark S. Swip. Cyclic references are references that reference itself. For an example, if you add a list itself, the list references itself and the values in cyclical list reference the list and the reference counting can't be like that. So Mark S. Swip marks every reachable object and swipes rest and the reachable objects get next to the next generation. And this generation helps GC to find cyclic references easily. So how to track or manage them? Python has internal stuff like GC. GC is an interface to garbage collector. There is a function here that creates a list and this happens itself. I call it ten times. Then I call GC.collect. It runs Mark S. Swip operation and returns total amount of collected objects here. And before that I disabled automatic GC. So it doesn't start without my command. Then I called it and you can see there is ten objects free. And you can check if an object track it by garbage collector. By default, atomic types is not going to be track it and non-atomic types is going to be track it. If you have ever written a C extension to Python or use a C module or use a Python application that consumes more memory than it needs, there might be a memory leak. So in Python 3 there is a module came. It's called trace malloc. It traces malloc operations and helps you to find a memory leak. So in Python 3 there is a module came. It's called trace malloc. It traces malloc operations and helps you to find memory leaks. It's a start function. It takes frames. I'm just using one frame here. But if you have complex code you can increase that frame amount. Then I take a snapshot. It contains relevant information about malloc. And you can take more snapshots and compare snapshots. They can compare. Then I access the stats of snapshots and get traceback. It's the biggest memory leak. And then I print relevant information about that. Trace malloc is a very cool module and it has a great API. And for the Python. And there is debug malloc stats. It's a raw interface of trace malloc. This is a Python interface. And this is a raw interface of malloc. You can call it with sys.debug malloc stats or you can set an environment variable to something. There are different Python memory allocates. For example malloc or pi malloc. Or you can write your own memory allocator. Python is a flexible language. It supports new memory allocators. Any questions? Thank you for listening. Thank you.
 Hello everyone, my name is Batuan. I'm a student from Turkey. In this session we are going  to talk about C Python's memory management. C Python is the major implementation of Python  language and there are other implementations like PyPy with their own memory management.  There are implementations like Jyton and Iron Python. They use their written language memory  management. For example, Jyton use JVM's memory management. This talk contains a lot of implementation  details so you can most of find stuff in docs. Why should you learn memory management concepts?  It will show you behind the curtain. For an example, you may think why Python doesn't  release memory back to the system or how it finds and detects side of references. All  of them has an answer in behind the curtain. You are going to learn how to control it.  Python has an interface for all internal things like abstraction texture they mentioned, parser,  and it has an interface for garbage collector. You can control it. There are helper functions  like sys.getref count. You can learn stuff of an object in memory. Although it seems  unnecessary to learn them, Instagram increased their performance by 10% with disabling or  enabling QC whenever they need. You are going to handle memory links, find them, and trace  them into source with understanding of memory management. All locations of memory, memory  management, we can examine memory management in two sections, allocation and allocation.  Before we start, don't forget everything is an object in Python. In that memory, everything  can be objects. Every Python object has two common fields. One is reference count and  the other one is object itself. Reference count is the count of total reference made  to that object. If you set A to 10 and B to 10, you will increase 10's reference count  by 2. If you delete or set A and B to another object, you will decrease reference count by  2. If an object's reference count reaches 0, it will immediately be allocated. But there  are some cases like object reference itself and it could not be deducted by reference  count manager. So there is a GC. There are type pointers. It points object itself. It  contains value of object, type of object, name of object, every attribute of object. It is  memory management module of C Python. In the top layer, layer 3, there is Python objects  and some of internal stuff. In the layer 2, there is Python's object allocator. It abstracts  memory and manages objects. In the layer 1, there is Python's raw memory allocator. It  ensures there is enough space in heap. If not, it requests memory from layer 0. Layer  0 is a system allocator. If you didn't change anything and using a standard Linux distribution,  it might be malloc. And in bottom layers, there are physical and low things we are not  talking about. Python divides objects into sections. If an object is bigger than a small  object threshold, it is called as big. If not, it is called as small. Small object threshold  is a static constant that defined in malloc.c in C Python repository. It is 512 bytes by  default. Big objects, it is not one of our concerns. Python direct routes big objects  to a system allocator with a set of verpes. Small objects, they manage it by layer 2 with  three levels of obstructions. The first one is blocks. They encapsulate Python objects  and pools and comps. They have the same size blocks and their size is 4 kilobytes, same  as a virtual memory page. And there are arenas. They contain 64 pools. Blocks, first level  of obstructions. The size of block determined with 8 bytes alignment notation. For an example,  you have 30 bytes sized object. It will be put to the 32 bytes sized block. And whenever  your object is downlocated, Python can put another object in a range of 25 to 32, to  that same block. It brings optimization. And there are size IDX value. It has pools  to contain same size blocks. Implementation of blocks, they design for containing Python  objects. They use 8 byte alignment notation for better management of free blocks. And  they mark this free and link to free blocks list of their pools when their object is downlocated.  Pools, they encapsulate same size blocks. Their size is 4 kilobytes. Every pool has a  pool header over it. It contains a list of free blocks. Next time, previous pools, the  arena index of memory, the size IDX of blocks inside and some memory stuff. Pool says free  blocks list. The list contains free blocks. And whenever a block free, it inserts that  list. There are states of blocks. Use it means it's neither empty nor full. At this one block  is free and at this one block is currently used. The full means there is no currently  available blocks. And the empty means every block is empty. And it will be linked to free  pools list of its arena. Arenas, they encapsulate pools. There's an overhead pool and they  are double linked lists with next arena, previous pools. Their size is 256 kilobytes. Stim  allocator only allocates space for arenas. And the other abstractions use space for arena  space. And Python only releases memory back to the system when all pools is empty in that  arena. Object specific. There are some object specific cases that's related with memory  management. For example, string attorney. Python strings are immutable seconds of unicode.  So Python can reference same string twice instead of creating any string in every operation.  We call it string interning. If a string is simple, it will be interred and doesn't  create twice. Simple strings are escalators, digits and underscores. For example, what  one is a simple string. And this happens in compile time, so function calls and constructors  doesn't affect that. And there is small integers. It's optimization for C Python. Python preallocates  integers between negative 5 to 256. There are internal references to integers and it brings  optimizations. There is garbage collection. Before we start talking about garbage collection,  don't forget Python has not variables. It has names instead. And difference between names  and variables only points to an object that lives in heap. Variables contain objects value.  Reference is the pointer to that object that lives in heap. And reference count, as I mentioned,  the total reference is made to that object. There's good size and best size of reference  counting. It's easy to find unused objects and it doesn't require a marking time like  in Mark S. Swip. But there are bad sites. Every Python object contains a reference count  field and it costs object over it. It doesn't support for cyclic references. And it is  one of the reasons of Jill. If Jill doesn't exist and two threads tries to increase an  object's n values reference count, it will cause memory leaks. And that will be bad.  And there is generational GC for cyclic references. Python runs this GC periodically. It uses  an algorithm called Mark S. Swip. Cyclic references are references that reference itself. For  an example, if you add a list itself, the list references itself and the values in cyclical  list reference the list and the reference counting can't be like that. So Mark S. Swip  marks every reachable object and swipes rest and the reachable objects get next to the  next generation. And this generation helps GC to find cyclic references easily.  So how to track or manage them? Python has internal stuff like GC. GC is an interface  to garbage collector. There is a function here that creates a list and this happens  itself. I call it ten times. Then I call GC.collect. It runs Mark S. Swip operation and returns  total amount of collected objects here. And before that I disabled automatic GC. So it  doesn't start without my command. Then I called it and you can see there is ten objects  free. And you can check if an object track it by garbage collector. By default, atomic  types is not going to be track it and non-atomic types is going to be track it. If you have ever written a C extension to Python or  use a C module or use a Python application that consumes more memory than it needs, there might be a memory leak. So in Python 3 there is a module came. It's called trace  malloc. It traces malloc operations and helps you to find a memory leak. So in Python 3 there  is a module came. It's called trace malloc. It traces malloc operations and helps you  to find memory leaks. It's a start function. It takes frames. I'm just using one frame  here. But if you have complex code you can increase that frame amount. Then I take a  snapshot. It contains relevant information about malloc. And you can take more snapshots  and compare snapshots. They can compare. Then I access the stats of snapshots and get traceback.  It's the biggest memory leak. And then I print relevant information about that. Trace malloc  is a very cool module and it has a great API. And for the Python. And there is debug malloc  stats. It's a raw interface of trace malloc. This is a Python interface. And this is a  raw interface of malloc. You can call it with sys.debug malloc stats or you can set an  environment variable to something. There are different Python memory allocates. For example  malloc or pi malloc. Or you can write your own memory allocator. Python is a flexible  language. It supports new memory allocators. Any questions? Thank you for listening. Thank  you.
Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_0_431.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_432_827.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_828_2231.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_2232_2555.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_2556_3119.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_3120_4787.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_4788_5891.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_5892_6443.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_6444_6707.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_6708_8903.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_8904_9455.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_9456_10463.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_10464_11339.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_11340_11591.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_11592_13799.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_13800_16835.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_16836_18443.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_18444_20411.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_20412_20723.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_20724_20843.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_20844_21707.png Memory_Management_in_Python_A_Short_Overview_of_CPythons_Memory_Management_ezvAqsd9sjc_21708_22195.png
Hello everyone, my name is Batuan. I'm a student from Turkey. In this session we are going to talk about C Python's memory management. C Python is the major implementation of Python language and there are other implementations like PyPy with their own memory management. There are implementations like Jyton and Iron Python. They use their written language memory management. For example, Jyton use JVM's memory management. This talk contains a lot of implementation details so you can most of find stuff in docs. Why should you learn memory management concepts? It will show you behind the curtain. For an example, you may think why Python doesn't release memory back to the system or how it finds and detects side of references. All of them has an answer in behind the curtain. You are going to learn how to control it. Python has an interface for all internal things like abstraction texture they mentioned, parser, and it has an interface for garbage collector. You can control it. There are helper functions like sys.getref count. You can learn stuff of an object in memory. Although it seems unnecessary to learn them, Instagram increased their performance by 10% with disabling or enabling QC whenever they need. You are going to handle memory links, find them, and trace them into source with understanding of memory management. All locations of memory, memory management, we can examine memory management in two sections, allocation and allocation. Before we start, don't forget everything is an object in Python. In that memory, everything can be objects. Every Python object has two common fields. One is reference count and the other one is object itself. Reference count is the count of total reference made to that object. If you set A to 10 and B to 10, you will increase 10's reference count by 2. If you delete or set A and B to another object, you will decrease reference count by 2. If an object's reference count reaches 0, it will immediately be allocated. But there are some cases like object reference itself and it could not be deducted by reference count manager. So there is a GC. There are type pointers. It points object itself. It contains value of object, type of object, name of object, every attribute of object. It is memory management module of C Python. In the top layer, layer 3, there is Python objects and some of internal stuff. In the layer 2, there is Python's object allocator. It abstracts memory and manages objects. In the layer 1, there is Python's raw memory allocator. It ensures there is enough space in heap. If not, it requests memory from layer 0. Layer 0 is a system allocator. If you didn't change anything and using a standard Linux distribution, it might be malloc. And in bottom layers, there are physical and low things we are not talking about. Python divides objects into sections. If an object is bigger than a small object threshold, it is called as big. If not, it is called as small. Small object threshold is a static constant that defined in malloc.c in C Python repository. It is 512 bytes by default. Big objects, it is not one of our concerns. Python direct routes big objects to a system allocator with a set of verpes. Small objects, they manage it by layer 2 with three levels of obstructions. The first one is blocks. They encapsulate Python objects and pools and comps. They have the same size blocks and their size is 4 kilobytes, same as a virtual memory page. And there are arenas. They contain 64 pools. Blocks, first level of obstructions. The size of block determined with 8 bytes alignment notation. For an example, you have 30 bytes sized object. It will be put to the 32 bytes sized block. And whenever your object is downlocated, Python can put another object in a range of 25 to 32, to that same block. It brings optimization. And there are size IDX value. It has pools to contain same size blocks. Implementation of blocks, they design for containing Python objects. They use 8 byte alignment notation for better management of free blocks. And they mark this free and link to free blocks list of their pools when their object is downlocated. Pools, they encapsulate same size blocks. Their size is 4 kilobytes. Every pool has a pool header over it. It contains a list of free blocks. Next time, previous pools, the arena index of memory, the size IDX of blocks inside and some memory stuff. Pool says free blocks list. The list contains free blocks. And whenever a block free, it inserts that list. There are states of blocks. Use it means it's neither empty nor full. At this one block is free and at this one block is currently used. The full means there is no currently available blocks. And the empty means every block is empty. And it will be linked to free pools list of its arena. Arenas, they encapsulate pools. There's an overhead pool and they are double linked lists with next arena, previous pools. Their size is 256 kilobytes. Stim allocator only allocates space for arenas. And the other abstractions use space for arena space. And Python only releases memory back to the system when all pools is empty in that arena. Object specific. There are some object specific cases that's related with memory management. For example, string attorney. Python strings are immutable seconds of unicode. So Python can reference same string twice instead of creating any string in every operation. We call it string interning. If a string is simple, it will be interred and doesn't create twice. Simple strings are escalators, digits and underscores. For example, what one is a simple string. And this happens in compile time, so function calls and constructors doesn't affect that. And there is small integers. It's optimization for C Python. Python preallocates integers between negative 5 to 256. There are internal references to integers and it brings optimizations. There is garbage collection. Before we start talking about garbage collection, don't forget Python has not variables. It has names instead. And difference between names and variables only points to an object that lives in heap. Variables contain objects value. Reference is the pointer to that object that lives in heap. And reference count, as I mentioned, the total reference is made to that object. There's good size and best size of reference counting. It's easy to find unused objects and it doesn't require a marking time like in Mark S. Swip. But there are bad sites. Every Python object contains a reference count field and it costs object over it. It doesn't support for cyclic references. And it is one of the reasons of Jill. If Jill doesn't exist and two threads tries to increase an object's n values reference count, it will cause memory leaks. And that will be bad. And there is generational GC for cyclic references. Python runs this GC periodically. It uses an algorithm called Mark S. Swip. Cyclic references are references that reference itself. For an example, if you add a list itself, the list references itself and the values in cyclical list reference the list and the reference counting can't be like that. So Mark S. Swip marks every reachable object and swipes rest and the reachable objects get next to the next generation. And this generation helps GC to find cyclic references easily. So how to track or manage them? Python has internal stuff like GC. GC is an interface to garbage collector. There is a function here that creates a list and this happens itself. I call it ten times. Then I call GC.collect. It runs Mark S. Swip operation and returns total amount of collected objects here. And before that I disabled automatic GC. So it doesn't start without my command. Then I called it and you can see there is ten objects free. And you can check if an object track it by garbage collector. By default, atomic types is not going to be track it and non-atomic types is going to be track it. If you have ever written a C extension to Python or use a C module or use a Python application that consumes more memory than it needs, there might be a memory leak. So in Python 3 there is a module came. It's called trace malloc. It traces malloc operations and helps you to find a memory leak. So in Python 3 there is a module came. It's called trace malloc. It traces malloc operations and helps you to find memory leaks. It's a start function. It takes frames. I'm just using one frame here. But if you have complex code you can increase that frame amount. Then I take a snapshot. It contains relevant information about malloc. And you can take more snapshots and compare snapshots. They can compare. Then I access the stats of snapshots and get traceback. It's the biggest memory leak. And then I print relevant information about that. Trace malloc is a very cool module and it has a great API. And for the Python. And there is debug malloc stats. It's a raw interface of trace malloc. This is a Python interface. And this is a raw interface of malloc. You can call it with sys.debug malloc stats or you can set an environment variable to something. There are different Python memory allocates. For example malloc or pi malloc. Or you can write your own memory allocator. Python is a flexible language. It supports new memory allocators. Any questions? Thank you for listening. Thank you.
from Turkey. In this session we are going to talk you can most of find stuff in docs. Why should to the system or how it finds and detects side of references. All of them has an answer in behind control it. Python has an interface for all learn stuff of an object in memory. Although it two sections, allocation and allocation. Before not talking about. Python divides objects into sections. If an object is bigger than a small object threshold, it is called as big. If not, it is called as small. Small object threshold is a they manage it by layer 2 with three levels of first level of obstructions. The size of block And Python only releases memory back to the object that lives in heap. And reference count, reference counting. It's easy to find unused generational GC for cyclic references. Python a very cool module and it has a great API. And