Di mana variabel python disimpan?

Sebagai ilmuwan data, biasanya, kami tidak memperhatikan bagaimana Python dan sistem operasi yang mendasarinya menangani memori untuk kode kami. Lagi pula, Python adalah bahasa paling populer di kalangan data scientist, sebagian karena secara otomatis menangani detail tersebut. Selama kami mengerjakan kumpulan data kecil, mengabaikan cara Python mengelola memori (mis. e. , alokasi memori dan dealokasi) tidak memengaruhi kinerja kode kami. Namun, begitu kita beralih ke kumpulan data besar (big data) atau proyek pemrosesan berat, pengetahuan dasar tentang manajemen memori menjadi sangat penting.

Sebagai contoh, saya sedang mengerjakan proyek ilmu data tentang pengindeksan DNA manusia. Saya menggunakan objek kamus python untuk melacak urutan (mis. e. , urutan nukleotida) dan menyimpan lokasinya dalam referensi DNA manusia. Sekitar 10% dalam proses, objek kamus mengambil semua RAM saya dan mulai bertukar antara disk dan RAM. Itu membuat prosesnya sangat lambat (karena disk jauh lebih lambat dalam transmisi data). Sebagai data scientist, jika saya mengetahui dasar-dasar Python dan manajemen memori, saya dapat mencegahnya dan membuat kode yang lebih hemat memori

Dalam artikel ini dan artikel mendatang, saya menjelaskan beberapa konsep dasar seputar manajemen memori dengan Python. Di akhir artikel ini, Anda memiliki pengetahuan dasar yang baik tentang bagaimana Python menangani alokasi dan dealokasi memori. Mari kita mulai…

Dasar

Program python adalah kumpulan dari

  1. metode
  2. referensi
  3. objek

Metode atau operasinya mudah. Saat Anda menambahkan dua angka, pada dasarnya Anda menerapkan metode tambah (atau jumlah) ke dua nilai. Referensi sedikit rumit untuk dijelaskan. Referensi adalah nama yang kami gunakan untuk mengakses nilai data (mis. e. , Sebuah Objek). Referensi paling terkenal dalam pemrograman adalah variabel. Saat Anda mendefinisikan

>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
0 ,
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
1 adalah variabel atau referensi dan
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
2 adalah nilainya (lebih akurat objek bilangan bulat). Selain variabel, atribut dan item adalah dua referensi populer lainnya dalam pemrograman

Sekarang, mari masuk lebih dalam dan perkenalkan objek. Sebagai programmer Python, Anda pasti pernah mendengar bahwa “Semua yang ada di Python adalah objek. ” Bilangan bulat adalah objek. String adalah objek. Daftar, kamus, tupel, bingkai data panda, larik NumPy adalah objek. Bahkan fungsi adalah objek. Saat kita membuat objek, itu akan disimpan di memori. Ketika kami mendefinisikan referensi di paragraf sebelumnya, saya seharusnya memberi tahu Anda bahwa referensi tidak menunjuk ke nilai dalam Python tetapi menunjuk ke alamat memori suatu objek. Misalnya, dalam contoh sederhana kami

>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
0 referensi x menunjuk ke alamat memori tempat objek integer
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
2 disimpan

Tumpukan Memori vs. Memori Tumpukan

Pada saat dijalankan, memori komputer terbagi menjadi beberapa bagian. Tiga bagian memori penting adalah

  1. Kode
  2. Tumpukan
  3. Tumpukan

Bagian kode (juga disebut Teks atau Instruksi) dari memori menyimpan instruksi kode dalam bentuk yang dimengerti mesin. Mesin mengikuti instruksi di bagian kode. Menurut instruksi, juru bahasa Python memuat fungsi dan variabel lokal di Stack Memory (juga disebut Stack). Memori tumpukan bersifat statis dan sementara. Statis berarti ukuran nilai yang disimpan dalam Stack tidak dapat diubah. Berarti sementara, segera setelah fungsi yang dipanggil mengembalikan nilainya, fungsi dan variabel terkait akan dihapus dari Stack. Sebagai ilmuwan data dan pemrogram, Anda tidak memiliki akses ke memori Stack. Penerjemah Python dan manajemen memori OS bersama-sama menangani bagian memori ini

Seperti yang Anda pelajari, variabel (atau referensi secara umum) hanya menyimpan alamat memori objek. Jadi, di mana benda-benda itu? . Untuk menyimpan objek, kita memerlukan memori dengan alokasi memori dinamis (mis. e. , ukuran memori dan objek dapat berubah). Interpreter Python secara aktif mengalokasikan dan membatalkan alokasi memori di Heap (apa yang harus dilakukan programmer C/C++ secara manual. Terima kasih, Piton. ). Python menggunakan algoritme pengumpulan sampah (disebut Garbage Collector) yang menjaga memori Heap tetap bersih dan membuang objek yang tidak diperlukan lagi

Anda tidak perlu mengotak-atik Heap, tetapi lebih baik memahami bagaimana Python mengelola Heap karena sebagian besar data Anda disimpan di bagian memori ini

Mari temukan alamat memori di Heap yang ditunjuk oleh variabel

>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
1. Untuk mengetahuinya, kita bisa menggunakan fungsi yang bernama
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
6

>>> x = 1
>>> id(x)
140710407579424
>>> hex(id(x))
'0x7ff9b1dc2720'

Saat kami menjalankan baris pertama (

>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
_0), Python menyimpan objek integer
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
2 di alamat memori
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
9 di komputer saya (berbeda dari milik Anda). Dalam ilmu komputer, kami biasanya menunjukkan alamat memori dalam angka heksadesimal; . awalan
>>> str1 = "Python"
>>> str2 = "Python"
>>> hex(id(str1))
'0x1e3adfe2830'
>>> hex(id(str2))
'0x1e3adfe2830'
1 digunakan dalam ilmu komputer untuk menunjukkan bahwa angka tersebut dalam hex). Setelah menyimpan objek int
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
2 dalam memori Heap, Python memberi tahu referensi (atau variabel)
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
1 untuk mengingat alamat ini (
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
9 atau
>>> str1 = "Python"
>>> str2 = "Python"
>>> hex(id(str1))
'0x1e3adfe2830'
>>> hex(id(str2))
'0x1e3adfe2830'
5) sebagai nilainya

Pengoptimalan Memori

Lihatlah contoh ini

>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'

Di sini, saya mendefinisikan dua variabel (

>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
_1 dan
>>> str1 = "Python"
>>> str2 = "Python"
>>> hex(id(str1))
'0x1e3adfe2830'
>>> hex(id(str2))
'0x1e3adfe2830'
7). Saya memberi mereka objek integer (mis. e.
>>> x = 1
>>> y = 1
>>> hex(id(x))
'0x7ffdf176a190'
>>> hex(id(y))
'0x7ffdf176a190'
2) kepada keduanya. Anehnya, alamat memori yang ditunjuk oleh kedua variabel adalah sama. Lihatlah contoh lain

>>> str1 = "Python"
>>> str2 = "Python"
>>> hex(id(str1))
'0x1e3adfe2830'
>>> hex(id(str2))
'0x1e3adfe2830'

Saya mendefinisikan dua variabel (

>>> str1 = "Python"
>>> str2 = "Python"
>>> hex(id(str1))
'0x1e3adfe2830'
>>> hex(id(str2))
'0x1e3adfe2830'
9 dan
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
0) dan menetapkan objek string (
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
1) untuk keduanya. Alamat memori yang ditunjuk oleh kedua variabel adalah sama. Jika Anda menguji hal yang sama untuk objek boolean, Anda akan melihat pengamatan serupa. Mengapa?

Untuk mengoptimalkan alokasi memori. Python melakukan proses yang disebut “magang. ” Untuk beberapa objek (akan dibahas nanti), Python hanya menyimpan satu objek di memori Heap dan meminta variabel yang berbeda untuk menunjuk ke alamat memori ini jika mereka menggunakan objek tersebut. Objek yang dilakukan Python untuk magang pada mereka adalah bilangan bulat [-5, 256], boolean, dan beberapa string. Magang tidak berlaku untuk jenis objek lain seperti bilangan bulat besar, sebagian besar string, float, daftar, kamus, tupel

Struktur Data Lebih Canggih

Sejauh ini, kami telah menunjukkan contoh struktur data sederhana seperti bilangan bulat, string, atau boolean. Bagaimana dengan struktur data yang lebih kompleks seperti daftar atau kamus

>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'

Contoh tersebut dengan jelas menunjukkan bahwa alamat memori dari objek daftar berbeda dari itemnya. Masuk akal karena daftar adalah kumpulan objek, masing-masing itemnya memiliki identitasnya sendiri dan merupakan objek terpisah dengan alamat memori yang berbeda.

Jika setiap item dalam daftar adalah objek tunggal, apakah pemagangan (dari bagian sebelumnya) berlaku untuk setiap item dalam daftar?

>>> a = 1
>>> b = 257
>>> hex(id(a))
‘0x7ffdf176a190’
>>> hex(id(b))
‘0x236330dc450’

Seperti yang Anda lihat, baik

>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
2 dan
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
3 menunjuk ke alamat memori yang sama karena magang bilangan bulat. Juga, Anda dapat melihat, ketika bilangan bulat melampaui 256, baik
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
4 dan
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
5 menunjuk ke alamat memori yang berbeda

Apa yang terjadi saat kami menambahkan item baru ke daftar. Apakah alamat memori berubah?

>>> lst = [1, 2, 3]
>>> hex(id(lst))
'0x23633104888'
>>> lst.append(4)
>>> lst
[1, 2, 3, 4]
>>> hex(id(lst))
'0x23633104888'

Menariknya, alamat memori untuk daftar tersebut tetap sama. Alasannya adalah daftar adalah objek yang bisa berubah, dan jika Anda menambahkan item ke dalamnya, objek tersebut masih merupakan objek yang sama dengan satu item lagi

Fakta penting lainnya tentang objek yang dapat berubah adalah bahwa jika Anda membuat contoh variabel yang berbeda dari suatu objek, semuanya akan berubah jika Anda membuat perubahan apa pun pada objek tersebut. Biarkan saya menunjukkannya dengan kode sederhana

>>> lst1 = [1, 2, 3]
>>> lst2 = lst1
>>> lst1.append(4)
>>> lst2
[1, 2, 3, 4]
>>> lst2.append(5)
>>> lst1
[1, 2, 3, 4, 5]

Dalam contoh ini, kedua variabel

>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
_6 dan
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
7 menunjuk ke objek yang dapat diubah yang sama (i. e.
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
_8). Jika salah satu dari variabel tersebut mengubah objek (mis. g. , tambahkan item baru), nilai variabel lain (yang menunjuk ke objek yang sama) juga akan berubah. Satu-satunya cara untuk mendapatkan salinan terpisah dari objek yang dapat diubah adalah dengan menggunakan metode
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
9

>>> lst1 = [1, 2, 3]
>>> lst2 = lst1.copy()
>>> lst1.append(4)
>>> lst2
[1, 2, 3]
>>> hex(id(lst1))
'0x236330dfe08'
>>> hex(id(lst2))
'0x236330e0c88'

Seperti yang Anda lihat, menggunakan metode

>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
_9, kami membuat dua objek daftar terpisah dengan alamat memori berbeda yang mengubah salah satunya tidak mengubah yang lain

Hampir semua yang kami katakan tentang objek daftar juga berlaku untuk objek kamus. Ada beberapa perbedaan halus yang berada di luar artikel ini. Misalnya, cara ukuran memori mereka bertambah setelah menambahkan item baru akan berbeda

Untuk memeriksa apakah dua atau lebih variabel menunjuk ke objek yang sama, Anda tidak perlu memeriksa alamat memorinya. Anda dapat memeriksa apakah dua variabel menunjuk ke objek yang sama menggunakan

>>> a = 1
>>> b = 257
>>> hex(id(a))
‘0x7ffdf176a190’
>>> hex(id(b))
‘0x236330dc450’
1. Ini sebuah contoh

>>> lst1 = [1, 2, 3]
>>> lst2 = lst1
>>> lst3 = lst1.copy()
>>> lst2 is lst1
True
>>> lst3 is lst1
False

Ingat,

>>> a = 1
>>> b = 257
>>> hex(id(a))
‘0x7ffdf176a190’
>>> hex(id(b))
‘0x236330dc450’
_1 berbeda dengan
>>> a = 1
>>> b = 257
>>> hex(id(a))
‘0x7ffdf176a190’
>>> hex(id(b))
‘0x236330dc450’
3.
>>> a = 1
>>> b = 257
>>> hex(id(a))
‘0x7ffdf176a190’
>>> hex(id(b))
‘0x236330dc450’
1 memberi tahu Anda jika dua objek sama tetapi
>>> a = 1
>>> b = 257
>>> hex(id(a))
‘0x7ffdf176a190’
>>> hex(id(b))
‘0x236330dc450’
3 memberi tahu Anda jika konten atau nilainya sama. Misalnya, pada kode sebelumnya, isi dari
>>> a = 1
>>> b = 257
>>> hex(id(a))
‘0x7ffdf176a190’
>>> hex(id(b))
‘0x236330dc450’
6 dan
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
6 adalah sama (i. e.
>>> lst = [1, 2, 3, 257]
>>> hex(id(lst))
'0x236330edf88'
>>> hex(id(lst[0]))
'0x7ffdf176a190'
>>> hex(id(lst[3]))
'0x7ffdf176a1b0'
_8), tetapi mereka adalah dua objek yang terpisah dan berbeda. Kode berikut menunjukkannya dengan jelas

>>> lst3 == lst1
True
>>> lst3 is lst1
False
_Ringkasan

Artikel ini memberi Anda pengetahuan dasar tentang bagaimana Python (lebih akurat implementasi CPython) mengalokasikan memori ke objek. Saat mengerjakan data besar dengan Python, Anda perlu mengetahui konsep dasar ini untuk menulis kode yang lebih hemat memori

Di mana variabel Python disimpan?

Karena ada tumpukan ruang memori yang tersedia dalam proses alokasi dan de – alokasi, itulah mengapa ini dikenal sebagai tumpukan memori . Variabel yang diperlukan secara global dalam program disimpan dalam memori heap. Contoh. Piton.

Bagaimana cara Python menyimpan data dalam variabel?

Operator penugasan, dilambangkan dengan simbol “=”, adalah operator yang digunakan untuk menetapkan nilai ke variabel dalam Python . Baris x=1 mengambil nilai yang diketahui, 1, dan menugaskan nilai itu ke variabel dengan nama "x". Setelah mengeksekusi baris ini, angka ini akan disimpan ke dalam variabel ini.

Apakah variabel dalam Python memiliki lokasi di memori?

Kita dapat melihat lokasi alamat memori dari nilai tersebut dengan fungsi id() . Pikirkan nomor panjang itu sebagai stoples penyimpanan. Saya dapat memeriksa lokasi nilai yang terkait dengan peanut_butter dengan meneruskan variabel saya ke fungsi id().

Di mana variabel disimpan?

Variabel biasanya disimpan di RAM . Ini ada di heap (mis. g. semua variabel global biasanya pergi ke sana) atau di tumpukan (semua variabel yang dideklarasikan dalam metode/fungsi biasanya pergi ke sana). Stack dan Heap keduanya RAM, hanya berbeda lokasi. Pointer memiliki aturan yang berbeda.