পাইথন স্মৃতি ফাঁস [বন্ধ]


180

আমার একটি দীর্ঘ-চলমান স্ক্রিপ্ট রয়েছে যা যদি দীর্ঘ পর্যায়ে চালাতে দেওয়া হয় তবে তা আমার সিস্টেমে সমস্ত স্মৃতি গ্রাস করবে।

স্ক্রিপ্ট সম্পর্কে বিশদে না গিয়ে আমার দুটি প্রশ্ন রয়েছে:

  1. অনুসরণ করার জন্য কি কোনও "সেরা অভ্যাস" রয়েছে, যা ফাঁস হওয়ার থেকে রোধ করতে সহায়তা করবে?
  2. পাইথনে মেমরি ফাঁস ডিবাগ করার কী কৌশল রয়েছে?

5
আমি এই রেসিপি সাহায্যকারী পেয়েছি ।
ডেভিড স্কেইন

দেখে মনে হচ্ছে এটি প্রচুর পরিমাণে ডেটা কার্যকর হতে পারে
কেসব্যাশ

1
@ ক্যাসাব্যাশ: যদি সেই ফাংশনটি কিছু প্রিন্ট করে আপনি গুরুতরভাবে এটি ভুল করছেন। এটি __del__এমন পদ্ধতি সহ অবজেক্টগুলিকে তালিকাবদ্ধ করে যা তাদের চক্র ব্যতীত আর উল্লেখ করা হয় না। সমস্যাটি হওয়ায় চক্রটি ভাঙা যায় না __del__। ঠিক কর!
হেলমুট গ্রোহনে

উত্তর:


106

এই নিবন্ধটি দেখুন: পাইথন মেমরি ফাঁস ট্র্যাকিং

এছাড়াও, নোট করুন যে আবর্জনা সংগ্রহের মডিউলটি আসলে ডিবাগ পতাকা সেট করতে পারে। তাকান set_debugফাংশন। অধিকন্তু, কল দেওয়ার পরে তৈরি করা বস্তুর প্রকারগুলি নির্ধারণের জন্য জনিবলার এই কোডটি দেখুন ।


83

আমি পূর্বে উল্লিখিত বেশিরভাগ বিকল্পগুলি চেষ্টা করে দেখেছি তবে এই ছোট এবং স্বজ্ঞাত প্যাকেজটি সেরা: পাইপ্পলার হিসাবে পাওয়া গেছে

আবর্জনা-সংগ্রহ করা হয়নি এমন বস্তুর সন্ধান করা এটি বেশ সোজা এগিয়ে, এই ছোট উদাহরণটি দেখুন:

এর মাধ্যমে প্যাকেজ ইনস্টল করুন pip install pympler

from pympler.tracker import SummaryTracker
tracker = SummaryTracker()

# ... some code you want to investigate ...

tracker.print_diff()

আউটপুট আপনাকে যুক্ত করা সমস্ত বস্তু, এবং মেমরির অতিরিক্তভাবে সেগুলি দেখায়।

নমুনা আউটপুট:

                                 types |   # objects |   total size
====================================== | =========== | ============
                                  list |        1095 |    160.78 KB
                                   str |        1093 |     66.33 KB
                                   int |         120 |      2.81 KB
                                  dict |           3 |       840 B
      frame (codename: create_summary) |           1 |       560 B
          frame (codename: print_diff) |           1 |       480 B

এই প্যাকেজটি আরও অনেকগুলি বৈশিষ্ট্য সরবরাহ করে। পিম্পলারের ডকুমেন্টেশন পরীক্ষা করুন , বিশেষত মেমরি ফাঁস চিহ্নিতকরণ বিভাগটি ।


5
এটি এতই টুকুনি pymplerহতে পারে ধীর । আপনি যদি আধা-রিয়েলটাইম কিছু করছেন তবে এটি আপনার অ্যাপ্লিকেশন কর্মক্ষমতা সম্পূর্ণ পঙ্গু করতে পারে।
ভুয়া নাম

@ এসপিপিক আশ্চর্যজনকভাবে আমার সাথেও একই ঘটনা ঘটে ... কেন এমন হচ্ছে তা আপনার কোনও ধারণা আছে ? উত্স কোডটিতে তাত্ক্ষণিকভাবে নজর দেওয়া কোনও বাস্তব অন্তর্দৃষ্টি দেয় নি।
লিনাস্গ

25

আমার তৈরি করা میم_টপ সরঞ্জামটি সুপারিশ করুন

এটি আমাকে অনুরূপ সমস্যা সমাধানে সহায়তা করেছিল

এটি তাত্ক্ষণিকভাবে পাইথন প্রোগ্রামে মেমরি ফাঁসের জন্য শীর্ষ সন্দেহভাজনদের দেখায়


1
এটি সত্য ... তবে এটি ব্যবহারের / ফলাফলের ব্যাখ্যার ক্ষেত্রে খুব সামান্য দেয়
me_

@ মাই_, এই সরঞ্জামটির "ব্যবহার" এবং "ফলাফল ব্যাখ্যা" বিভাগ দুটি নথিভুক্ত রয়েছে। "রেফগুলি হ'ল অবজেক্ট থেকে রেফারেন্সের গণনা, প্রকারগুলি এই ধরণের অবজেক্টের গণনা, বাইটস হ'ল অবজেক্টের আকার" - এটিকে কী নথিভুক্ত করা খুব স্পষ্ট হবে না?
ডেনিস রিজকভ

সরঞ্জামটির ব্যবহারের ডক্সগুলি "সময়ে সময়ে: লগিং.ডেবগ (মেম_টপ ())" বলে একটি একক লাইন দেয়, যদিও ফলাফলগুলির ব্যাখ্যাটি প্রসঙ্গ ছাড়াই লেখকের বাস্তব জীবনের ত্রুটি ট্র্যাকিংয়ের অভিজ্ঞতা ... এটি কোনও প্রযুক্তিগত বিবরণ নয় যা বলে তারা ঠিক কীভাবে তাকিয়ে আছে ... আমি আপনার উত্তরটি কড়া নাড়ছি ... এটি উচ্চ স্তরের সন্দেহভাজনদেরকে বিল হিসাবে দেখায় ... এটি ব্যবহারের ফলাফলকে পুরোপুরি বোঝার জন্য পর্যাপ্ত দলিল দেয় না ... উদাহরণস্বরূপ , "ফলাফল ব্যাখ্যা" আউটপুটে কেন "গিয়ারম্যানজব্রেকয়েস্ট" স্পষ্টতই সমস্যা? কেন ...
মে_

1
আমার ধারণা আমি অজান্তেই আপনার সরঞ্জামটি
কড়া নাড়ছি

6
@ মাই_, আমি "ব্যবহার" -এর পরবর্তী পদক্ষেপটি কেবল যুক্ত করেছি, "কাউন্টারগুলি" বিভাগ যুক্ত করেছি, ব্যাখ্যাটি যুক্ত করেছিলাম ঠিক কেন গিয়ারম্যান সেই বাস্তব জীবনের উদাহরণে সন্দেহজনক ছিলেন, কোডে "মেম_টপ ()" এর প্রতিটি optionচ্ছিক প্যারামিটার নথিভুক্ত করেছেন, এবং এগুলি v0.1.7 হিসাবে আপলোড করেছেন - দয়া করে আরও কিছু উন্নত করা যায় কিনা একবার দেখুন। ধন্যবাদ! )
ডেনিস রিজকভ

18

ট্রেসমলোক মডিউলটি পাইথন ৩.৪ থেকে শুরু করে বিল্ট-ইন মডিউল হিসাবে সংহত করা হয়েছিল এবং স্পষ্টতই এটি পাইথনের পূর্ববর্তী সংস্করণগুলির জন্য তৃতীয় পক্ষের লাইব্রেরি হিসাবে উপলব্ধ (যদিও এটি পরীক্ষিত হয়নি)।

এই মডিউলটি সুনির্দিষ্ট ফাইল এবং লাইনগুলি সর্বাধিক মেমরির বরাদ্দ করতে সক্ষম হয়। আইএমএইচও, এই তথ্যটি প্রতিটি ধরণের জন্য বরাদ্দকৃত সংখ্যার তুলনায় অসীম মূল্যবান (যা বেশিরভাগ সময় 99% টিপলস হিসাবে শেষ হয় যা একটি সূত্র, তবে বেশিরভাগ ক্ষেত্রে সবেই সহায়তা করে)।

আমি আপনাকে পাইরাসাইটের সাথে মিশ্রণে ট্রেসমেলোক ব্যবহার করার পরামর্শ দিচ্ছি । 10 9 বার, দৌড়ানো শীর্ষ 10 snippet একটি pyrasite-শেল আপনি যথেষ্ট তথ্য ও নির্দেশ 10 মিনিটের মধ্যে লিক ঠিক করতে দিতে হবে। তবুও, যদি আপনি এখনও ফাঁস কারণটি খুঁজে পেতে অক্ষম হন তবে এই থ্রেডে উল্লিখিত অন্যান্য সরঞ্জামগুলির সাথে মিশ্রিত পাইরেসাইট শেল সম্ভবত আপনাকে আরও কিছু ইঙ্গিত দেবে। পাইরেসাইট (যেমন মেমোরি ভিউয়ার) দ্বারা সরবরাহ করা সমস্ত অতিরিক্ত সহায়ক সম্পর্কেও আপনার একবার নজর দেওয়া উচিত।


pytracemalloc.readthedocs.io এর আর কোন অস্তিত্ব নেই
Dimitrios Mistriotis

12

আপনার গ্লোবাল বা স্ট্যাটিক ডেটা (দীর্ঘজীবী ডেটা) সম্পর্কে বিশেষভাবে নজর রাখা উচিত।

যখন এই ডেটা কোনও সীমাবদ্ধতা ছাড়াই বৃদ্ধি পায়, আপনি পাইথনে ঝামেলাও পেতে পারেন।

আবর্জনা সংগ্রহকারী কেবলমাত্র ডেটা সংগ্রহ করতে পারে, এটি আর উল্লেখ করা হয় না। তবে আপনার স্থিতিশীল ডেটা হ্রাস করতে পারে এমন ডেটা উপাদানগুলিকে যা মুক্ত করা উচিত।

আরেকটি সমস্যা স্মৃতিচক্র হতে পারে তবে কমপক্ষে তাত্ত্বিকভাবে আবর্জনা সংগ্রহকারীকে চক্রটি খুঁজে বের করতে হবে এবং নির্মূল করা উচিত - যতক্ষণ না তারা কিছু দীর্ঘ জীবন্ত তথ্যের উপর আবদ্ধ না হয়।

কোন ধরণের দীর্ঘকালীন ডেটা বিশেষত উদ্বেগজনক? যে কোনও তালিকা এবং অভিধানগুলিতে ভাল নজর রাখুন - এগুলি কোনও সীমা ছাড়াই বাড়তে পারে। অভিধানে আপনি এমনকি সমস্যাটি দেখতে পাচ্ছেন না যেহেতু আপনি যখন ডিক্টস অ্যাক্সেস করেন তখন অভিধানের কীগুলির সংখ্যা আপনার পক্ষে খুব বেশি দৃশ্যমান না হয় ...


7

দীর্ঘ চলমান প্রক্রিয়াগুলির জন্য মেমরি ফাঁস সনাক্ত এবং সনাক্ত করতে, যেমন উত্পাদন পরিবেশে, আপনি এখন স্ট্যাকিম্যাক্ট ব্যবহার করতে পারেন । এটি নীচে ট্রেসমলোক ব্যবহার করে । এই পোস্টে আরও তথ্য ।

এখানে চিত্র বর্ণনা লিখুন


4

সর্বোত্তম অনুশীলন হিসাবে, পুনরাবৃত্তি ফাংশন জন্য নজর রাখুন। আমার ক্ষেত্রে আমি পুনরাবৃত্তি নিয়ে সমস্যায় পড়েছি (যেখানে এটির দরকার ছিল না)। আমি যা করছিলাম তার একটি সরল উদাহরণ:

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    if my_flag:  # restart the function if a certain flag is true
        my_function()

def main():
    my_function()

এই পুনরাবৃত্তিমূলক উপায়ে অপারেশন আবর্জনা সংগ্রহকে ট্রিগার করবে না এবং ফাংশনটির অবশিষ্টাংশগুলি সাফ করবে না, তাই মেমরির মাধ্যমে প্রতিবার ব্যবহার বাড়ছে এবং বাড়ছে।

আমার সমাধানটি ছিল_আপনার ফাংশন () থেকে পুনরাবৃত্ত কলটি টেনে আনা এবং যখন আবার কল করার সময় প্রধান () হ্যান্ডেলটি রাখা হয়েছিল। এইভাবে ফাংশনটি স্বাভাবিকভাবেই শেষ হয় এবং নিজের পরে পরিষ্কার হয়ে যায়।

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    .....
    return my_flag

def main():
    result = my_function()
    if result:
        my_function()

7
আপনি পুনরাবৃত্তির গভীরতার সীমাটিতে চাপ দিলে এই পদ্ধতিতে পুনরাবৃত্তিটি ব্যবহার করাও ভেঙে যাবে কারণ পাইথন টেল কলগুলি অনুকূল করে না। ডিফল্টরূপে, এটি 1000 পুনরাবৃত্তি কল।
মিথ্যা রায়ান

3

পাইথনে মেমরি ফাঁসের জন্য "সেরা অভ্যাসগুলি" সম্পর্কে নিশ্চিত নন, তবে পাইথনটিকে আবর্জনা সংগ্রহকারী দ্বারা নিজের স্মৃতি পরিষ্কার করতে হবে। সুতরাং প্রধানত আমি কিছু সংক্ষিপ্তের বিজ্ঞপ্তি তালিকা পরীক্ষা করে শুরু করব, যেহেতু এগুলি আবর্জনা সংগ্রহকারী সংগ্রহ করবে না।


3
বা অবজেক্টের রেফারেন্স যা চিরকালের জন্য রাখা হচ্ছে ইত্যাদি ইত্যাদি
ম্যাট বি

3
আপনি কি দয়া করে বিজ্ঞপ্তিযুক্ত তালিকা এবং চিরকালের জন্য অবজেক্টের উদাহরণ সরবরাহ করতে পারেন?
ড্যানিয়েল

2

এটি কোনওভাবেই সম্পূর্ণ পরামর্শ নয় advice তবে ভবিষ্যতের মেমরি ফাঁস (লুপস) এড়ানোর চিন্তাভাবনার সাথে লেখার ক্ষেত্রে এক নম্বর জিনিসটি মনে রাখা উচিত তা নিশ্চিত করা যে কোনও কিছু যা কল-ব্যাকের কোনও রেফারেন্স গ্রহণ করে, সেই কল-ব্যাককে দুর্বল রেফারেন্স হিসাবে সংরক্ষণ করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.