Skip to content

Commit c89a724

Browse files
committed
implement memory management examples in Python
1 parent adb31a0 commit c89a724

File tree

3 files changed

+275
-0
lines changed

3 files changed

+275
-0
lines changed

.gitignore

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Virtual environment
10+
venv/
11+
env/
12+
ENV/
13+
.venv/
14+
.ENV/
15+
16+
# Jupyter Notebook checkpoints
17+
.ipynb_checkpoints
18+
19+
# PyInstaller
20+
*.manifest
21+
*.spec
22+
23+
# Installer logs
24+
pip-log.txt
25+
pip-delete-this-directory.txt
26+
27+
# Unit test / coverage reports
28+
htmlcov/
29+
.tox/
30+
.nox/
31+
.coverage
32+
coverage.xml
33+
*.cover
34+
*.py,cover
35+
.cache
36+
nosetests.xml
37+
test-results.xml
38+
39+
# MyPy
40+
.mypy_cache/
41+
.dmypy.json
42+
dmypy.json
43+
44+
# Pyre
45+
.pyre/
46+
47+
# Pytest
48+
.pytest_cache/
49+
50+
# pytype
51+
.pytype/
52+
53+
# IDEs
54+
.vscode/
55+
.idea/
56+
*.sublime-project
57+
*.sublime-workspace
58+
59+
# MacOS/Linux
60+
.DS_Store
61+
*.swp
62+
*.swo
63+
64+
# Logs
65+
*.log
66+
67+
# Python env config
68+
*.env
69+
.env.*
70+
.envrc
71+
72+
# Local builds
73+
build/
74+
dist/
75+
*.egg-info/
76+
.eggs/

inner-working/inner_working.py

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#Python Object Memory Allocation
2+
a = "Hello, World!" # The memory is allocated for this string object
3+
4+
# Assigning the same object to another variable
5+
b = a # No new memory is allocated; 'b' references the same object as 'a'
6+
7+
# Printing memory addresses of 'a' and 'b'
8+
print(f"Memory address of 'a': {id(a)}") # Output: Memory address of 'a'
9+
print(f"Memory address of 'b': {id(b)}") # Output: Memory address of 'b' (same as 'a')
10+
11+
# Creating a new object
12+
c = "Python" # New memory is allocated for this different string object
13+
14+
# Printing memory address of 'c'
15+
print(f"Memory address of 'c': {id(c)}") # Output: Memory address of 'c' (different from 'a' and 'b')
16+
17+
#output
18+
# Memory address of 'a': 126707795390512
19+
# Memory address of 'b': 126707795390512
20+
# Memory address of 'c': 11043008
21+
22+
23+
# Reference Counting in Python
24+
import sys # Importing sys module to access reference count
25+
26+
# Creating an object (a list in this case)
27+
my_list = [1, 2, 3]
28+
29+
# Checking the reference count of 'my_list'
30+
print(f"Initial reference count of 'my_list': {sys.getrefcount(my_list)}") # Output: Reference count
31+
32+
# Creating additional references to the same object
33+
ref1 = my_list
34+
ref2 = my_list
35+
36+
# Checking the updated reference count of 'my_list'
37+
print(f"Updated reference count of 'my_list': {sys.getrefcount(my_list)}") # Output: Increased reference count
38+
39+
# Deleting one reference
40+
del ref1
41+
42+
# Checking the reference count after deletion
43+
print(f"Reference count after deleting 'ref1': {sys.getrefcount(my_list)}") # Output: Decreased reference count
44+
45+
46+
#Python Garbage Collection
47+
import gc # Importing garbage collector module
48+
49+
# Defining a simple class to create objects
50+
class MyClass:
51+
def __init__(self, name):
52+
self.name = name
53+
54+
# Creating an object instance
55+
obj1 = MyClass("Object1")
56+
57+
# Checking if the object is tracked by garbage collector
58+
print(f"Is 'obj1' tracked by GC?: {gc.is_tracked(obj1)}") # Output: True
59+
60+
# Deleting the object reference
61+
del obj1
62+
63+
# Forcing garbage collection
64+
gc.collect()
65+
66+
# Checking the status after collection
67+
print("Garbage collection completed.")
68+
69+
#Memory Leaks and Circular References
70+
71+
import gc
72+
73+
# Defining two classes to create a circular reference
74+
class A:
75+
def __init__(self):
76+
self.b = None # Placeholder for an instance of B
77+
78+
class B:
79+
def __init__(self):
80+
self.a = None # Placeholder for an instance of A
81+
82+
# Creating instances of both classes
83+
obj_a = A()
84+
obj_b = B()
85+
86+
# Creating a circular reference
87+
obj_a.b = obj_b
88+
obj_b.a = obj_a
89+
90+
# Forcing garbage collection
91+
gc.collect()
92+
93+
# Breaking the circular reference
94+
obj_a.b = None
95+
obj_b.a = None
96+
97+
# Forcing garbage collection again
98+
gc.collect()
99+
100+
print("Circular reference has been handled.")
101+
102+
103+
# Explanation:
104+
105+
# Circular References: 'obj_a' references 'obj_b' and vice versa, forming a circular reference.
106+
# Garbage Collection Handling: Even with circular references, Python's garbage collector can detect and clean them up if references are broken ('gc.collect()').
107+
108+
109+
# Optimizing Memory Usage with '__slots__'
110+
111+
# Without __slots__
112+
class WithoutSlots:
113+
def __init__(self, name, age):
114+
self.name = name
115+
self.age = age
116+
117+
# With __slots__
118+
class WithSlots:
119+
__slots__ = ['name', 'age'] # Define allowed attributes
120+
121+
def __init__(self, name, age):
122+
self.name = name
123+
self.age = age
124+
125+
# Creating instances
126+
obj1 = WithoutSlots("Alice", 30)
127+
obj2 = WithSlots("Bob", 25)
128+
129+
# Checking the memory sizes
130+
import sys
131+
print(f"Memory usage without __slots__: {sys.getsizeof(obj1)} bytes") # Output: Memory size
132+
print(f"Memory usage with __slots__: {sys.getsizeof(obj2)} bytes") # Output: Reduced memory size
133+
134+
135+
# Explanation:
136+
137+
# '__slots__' Usage: Reduces memory usage by preventing the creation of a default '__dict__' for each instance.
138+
# Memory Optimization: The memory footprint is smaller for 'WithSlots' than for 'WithoutSlots'.
139+
140+
# Using Weak References
141+
142+
import weakref # Importing weakref module
143+
144+
# Defining a class to create objects
145+
class MyClass:
146+
def __init__(self, name):
147+
self.name = name
148+
149+
# Creating a strong reference
150+
obj = MyClass("MyObject")
151+
152+
# Creating a weak reference to the object
153+
weak_obj = weakref.ref(obj)
154+
155+
# Checking if weak reference is alive
156+
print(f"Is weak reference alive?: {weak_obj() is not None}") # Output: True
157+
158+
# Deleting the strong reference
159+
del obj
160+
161+
# Checking if weak reference is still alive
162+
print(f"Is weak reference alive after deleting strong reference?: {weak_obj() is not None}") # Output: False
163+
164+
165+
# Monitoring Memory Usage with psutil
166+
167+
# psutil (process and system utilities) is a cross-platform library for retrieving information on running processes and system utilization (CPU, memory, disks, network, sensors) in Python. It is useful mainly for system monitoring, profiling and limiting process resources and management of running processes.
168+
169+
import psutil # Importing the psutil module to monitor system performance
170+
171+
# Function to check memory usage
172+
def memory_usage():
173+
process = psutil.Process() # Get the current process
174+
mem_info = process.memory_info() # Get memory information
175+
print(f"Memory usage: {mem_info.rss / (1024 * 1024):.2f} MB") # Print memory usage in MB
176+
177+
# Creating a large list
178+
large_list = [i for i in range(1000000)]
179+
180+
# Checking memory usage
181+
memory_usage() # Output: Memory usage before clearing the list
182+
183+
# Clearing the list to free memory
184+
large_list.clear()
185+
186+
# Checking memory usage after clearing the list
187+
memory_usage() # Output: Reduced memory usage after clearing
188+
189+
190+
# Explanation:
191+
192+
# 'psutil' Library: Provides utilities to monitor memory and system performance.
193+
# Memory Monitoring: Demonstrates how memory usage changes before and after freeing up resources.

inner-working/memoryManagment.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Blog:-https://www.w3resource.com/python/python-memory-management-with-examples.php
2+
3+
4+
5+
6+

0 commit comments

Comments
 (0)