راهنمای جامع آشنایی با مشکل مموری لیک در جاوا و نحوه برطرف کردن آن‌

راهنمای جامع آشنایی با مشکل مموری لیک در جاوا و نحوه برطرف کردن آن‌

یکی از ویژگی‌های قدرتمند جاوا، توانایی مدیریت حافظه است. یک ویژگی کاربردی که باعث شده تا توسعه‌دهندگان زیادی جذب اکوسیستم جاوا شوند. به‌عنوان یک برنامه‌نویس جاوا، اشیاء را ایجاد می‌کنید و مولفه Garbage Collector جاوا مسئولیت تخصیص و آزادسازی حافظه را بر عهده می‌گیرد. البته این حرف بدان معنا نیست که جاوا بی عیب و نقص است و در واقع، مشکل نشت حافظه (Memory Leak) در برنامه‌های کاربردی جاوا نیز به وجود می‌آیند، اما در مقایسه با زبان‌های دیگری مثل سی‌پلاس‌پلاس (++C) این مورد کمتر است. اگر توسعه‌دهنده‌ای هستید که دوست دارد برنامه‌های بدون عیب بنویسد، نباید مشکل مموری لیک در برنامه‌تان وجود داشته باشد. به همین دلیل، این راهنما را برای شما گردآوری کرده‌ا‌یم تا اطلاعات کافی در ارتباط با مموری لیک، راهکارهای پیشگیری از بروز این مشکل و نحوه برطرف کردن آن‌ها را در اختیار داشته باشید. 

💎 برای آشنایی بیشتر با این زبان قدرتمند می توانید به دوره‌ی آموزش رایگان جاوا در سکان آکادمی مراجعه کنید.

آیا باید نگران مموری لیک یا همان نشست حافظه باشیم؟

در حالت کلی، مشکل مموری لیک (نشت حافظه)، در بخش‌های مشخص از منابع حافظه اصلی که مرتبط با برنامه کاربردی هستند و برنامه‌نویس انتظار بروز مشکل در ارتباط با آن مناطق را داشته به‌وجود می‌آیند. به‌طور مثال، برنامه‌نویس از مکانیزم‌های اعتبارسنجی در ارتباط با ورودی‌ها استفاده نکرده است. هنگامی که برنامه‌‌های شما یک استثناء java.lang.OutOfMemoryError را برمی‌گردانند، اولین موضوعی که باید به آن شک کنید، مموری لیک است. 

مموری لیک نشانه‌ای از یک طراحی ضعیف است. اگر از آن گروه برنامه‌نویسانی هستید که می‌خواهید همه کارها را به بهترین شکل انجام دهند، باید به دقت مواردی که ممکن است باعث بروز مشکل مموری لیک شوند را شناسایی کنید یا اگر نشانه‌ای از مموری لیک را مشاهده کردید به فکر برطرف کردن آن باشید. به عنوان یک برنامه‌نویس جاوا، هیچ راهی برای دانستن این موضوع که ماشین مجازی جاوا چه زمانی از مولفه Garbage Collector استفاده می‌کند، وجود ندارد. حتی زمانی‌که ()System.gc را فراخوانی می‌کنید. به‌ طور معمول، جمع‌آوری زباله زمانی اجرا می‌شود که حافظه آزاد سیستمی کم می‌شود یا برنامه کاربردی شما به مقداری فراتر از حافظه آزاد سیستم نیاز دارد. اگر مولفه Garbage Collector موفق نشود، منابع حافظه کافی را آزادسازی نکند، در این حالت، برنامه شما حافظه موردنیاز را از سیستم عامل درخواست می‌کند. 

مموری لیک در زبان برنامه‌نویسی جاوا در مقایسه با سی‌پلاس‌پلاس (++C) یا سایر زبان‌های برنامه‌نویسی همیشه باعث بروز یک مشکل جدی نمی‌شود. جیم پاتریک از توسعه‌دهندگان شرکت آی‌بی‌ام در این ارتباط می‌گوید :«هنگام بروز مشکل مموری لیک اگر دو حالت زیر را داشتید، احساس نگرانی کنید:

  1. اندازه نشتی.
  2. مدت حیات برنامه». 

یک برنامه کوچک جاوا ممکن است با مشکل مموری لیک روبرو شود، اما به احتمال زیاد مشکل جدی برای برنامه به وجود نمی‌آورد، به شرطی که ماشین مجازی جاوا حافظه اصلی کافی برای اجرای برنامه کاربردی داشته باشد. حال اگر برنامه جاوا شما به طور مداوم اجرا شود، مموری لیک مشکل‌ساز خواهد شد، زیرا برنامه به طور مداوم در حال اجرا است و در نهایت منابع حافظه را به سرعت مصرف می‌کند.

یکی دیگر از مواردی که مشکل مموری لیک را به مشکل بزرگی تبدیل می‌کند، زمانی است که برنامه تعداد زیادی اشیاء موقتی را فراخوانی می‌کند که حجم قابل توجهی از حافظه را مصرف می‌کنند. هنگامی که مرجع مربوط به این اشیاء اشغال‌کننده حافظه حذف نشوند، برنامه به سرعت با کمبود حافظه موردنیاز روبرو می‌شود. 

ماشین مجازی جاوا برای برنامه‌نویسان این زبان عملکردی شبیه به سپر دفاعی دارد و قادر است تا حدودی از بروز مشکلات غیرمنتظره پیشگیری کند، در حالی که برنامه‌نویسان زبان‌های دیگری مثل سی از این قابلیت ارزشمند محروم هستند. 

چگونه مانع بروز مشکل مموری لیک در جاوا شویم؟

برای پیشگیری از بروز مشکل مموری لیک، اولین نکته‌ای که باید رعایت کنید نحوه کدنویسی‌تان است. برای این منظور الگوهای مشخص و ساختارمندی وجود دارد که کمک می‌کنند بر مشکل مموری لیک غلبه کنید. 

1. از اشیاء مرجع برای پیشگیری از بروز مموری لیک استفاده کنید.

ریموند رایچرت (Raimond Reichert) از برنامه‌نویسان جاوا در وب‌سایت JavaWorld به این نکته اشاره دارد که می‌توانید از اشیاء مرجع برای حل مشکل مموری لیک استفاده کنید.

با استفاده از بسته java.lang.ref می‌توانید در برنامه خود با Garbage Collector در تعامل باشید. راهکار فوق مانع ارجاع مستقیم به اشیا می‌شود و اجازه می‌دهد از اشیاء مرجع خاصی استفاده کنید که Garbage Collector به سهولت قادر به پاک کردن آن‌ها است. زیرکلاس‌های ویژه به شما اجازه می‌دهند به طور غیر مستقیم به اشیا ارجاع دهید. به عنوان مثال، Reference سه زیر کلاس به نام‌های PhantomReference، SoftReference و WeakReference دارد. 

برای دسترسی به یک مرجع یا یک شی که ارجاع به آن توسط زیر‌کلاس‌های مذکور انجام می‌شود، متد get آن شی مرجع را در اختیارتان قرار دارد. مزیت استفاده از روش فوق‌الذکر این است که می‌توانید یک مرجع را با تنظیم مقدار null به سهولت پاک کنید. مولفهGarbage Collector چگونه با هر نوع مرجع رفتار می‌کند؟

شی SoftReference: مولفه Garbage Collector هنگامی که حافظه موردنیاز کم باشد، تمامی اشیاء SoftReference را پاک می‌کند. 

شئ WeakReference: هنگامی که Garbage Collector متوجه یک شی با ارجاع ضعیف شود، تمام ارجاعات به آن‌را پاک می‌‌کند و در نهایت شی را از حافظه حذف می‌کند. 

شیء PhantomReference: مولفه Garbage Collector نمی‌تواند اشیاء PhantomReference را به‌طور خودکار پاک کند و به شما اجازه می‌دهد به صورت دستی تمام اشیاء و مراجع PhantomReference را پاک کنید.

با استفاده از اشیاء مرجع، می‌توانید با مولفه Garbage Collector در تعامل باشید تا اشیایی که دسترسی ضعیفی به آن‌ها وجود دارد به‌طور خودکار حذف شوند. اشیاء WeakReference، به ویژه در هنگام پاک‌سازی حافظه می‌توانند به شما در پیشگیری از بروز خطاهای حافظه کمک کنند. 

2. مانع بروز مشکل مموری لیک در ارتباط با کلاس WebApp classloader شوید.

با استفاده از نگارش 7.6.6 Jetty یا بالاتر از آن، می‌توانید مانع سنجاق کردن کلاس لودر WebApp شوید. هنگامی که کد شما به طور مداوم به یک کلاس لودر WebApp ارجاع می‌دهد، مموری لیک دور از انتظار نیست. در این حالت با دو نوع نشتی روبرو می‌شوید که daemon threads و static fields نام دارند. 

فیلدهای ایستا (static fields) با مقدار کلاس‌لودر آغاز می‌شوند. حتی زمانی‌که Jetty فرآیند استقرار را متوقف می‌کند و اقدام به استقرار دوباره برنامه وب شما می‌کند، مرجع، ثابت باقی می‌ماند و به همین دلیل، این امکان وجود نخواهد داشت تا شیء را از حافظه پاک کرد.

Daemon threads؛ ریسمان‌های Daemon که خارج از چرخه حیات یک برنامه وب راه‌اندازی می‌شوند، عامل دیگر بروز مشکل مموری لیک هستند، زیرا این ریسمان‌ها/رشته‌ها ارجاعاتی به کلاس ‌لودری دارند که ریسمان‌ها را آغاز کرده است.

با Jetty، می‌توانید از مولفه‌هایی که پیشگیری‌کننده‌ (preventer) نام دارند، برای رفع مشکلات مرتبط با کلاس‌لودرهای WebApp استفاده کنید. به عنوان مثال، یک پیشگیری‌کننده از نشت زمینه (context) برنامه، مانند ()appcontext.getappcontext، به شما کمک می‌کند تا ارجاعات ثابت را در کلاس لودر (بارگذار) زمینه نگه دارید. از مولفه‌های دیگری که برای این منظور در اختیار برنامه‌نویسان جاوا قرار دارد به موارد زیر باید اشاره کرد: 

  • AWT leak preventer
  • DOM leak preventer
  • Driver manager leak preventer
  • GC thread leak preventer
  • Java2D leak preventer
  • LDAP leak preventer
  • Login configuration leak preventer
  • Security provider leak preventer

3. سایر مراحل خاص

راهکارهای دیگری نیز برای پیشگیری از بروز مشکل مموری لیک در جاوا وجود دارد که از آن جمله به موارد زیر باید اشاره کرد: 

  • آزادسازی نشست (Session)، هنگامی که دیگر نیازی به آن نیست. برای این کار از متد ()HttpSession.invalidate استفاده کنید.
  • کمترین مقدار time-out را برای هر نشست تعیین کنید. 
  • فقط داده‌های موردنیاز را در HttpSession ذخیره‌سازی کنید.
  • از مکانیزم الحاق رشته‌ها استفاده نکنید و به جای آن از متد ()Apend StringBuffer استفاده کنید، زیرا رشته یک شی غیرقابل تغییر است و مکانیزم الحاق رشته‌ها اشیاء غیر ضروری زیادی را ایجاد می‌کند. هنگامی که تعداد اشیاء موقت ساخته شده زیاد شوند، عملکرد برنامه به سرعت کاهش پیدا می‌کند. 
  • تا حد امکان، نباید HttpSession را در صفحه jsp ایجاد کنید، به جای آن می‌توانید از دستور Page به شرح زیر استفاده کنید:
<%@page session=”false”%>
  • اگر در حال نوشتن کوئری (query) هستید که قرار است به طور مکرر اجرا شود، به جای استفاده از شی Statement، از شی PreparedStatement استفاده کنید. چرا؟ PreparedStatement از قبل کامپایل می‌شود، در حالی که Statement هر بار که دستور SQL شما به پایگاه داده ارسال می‌شود، کامپایل می‌شود.
  • هنگام استفاده از دستورات JDBC و نوشتن محاوره‌ها از "*" استفاده نکنید و سعی کنید به جای آن از نام ستون مربوطه استفاده کنید.
  • اگر قرار است از یک ترکیب نحوی مثل stmt = con.prepareStatement(sql query) در یک حلقه (loop) استفاده کنید، اطمینان حاصل کنید که آن‌را محصور در یک حلقه مشخص کرده‌اید. 
  • هنگامی که نیاز به استفاده مجدد از آن‌ها دارید، حتما Statement و ResultSet را ببندید.
  • ResultSet، Connection، PreparedStatement و Statement را در بلوک final قرار دهید. 

وقتی مشکوک به مموری لیک هستیم چه اقدامی باید انجام دهیم؟ 

اگر متوجه شدید اجرای برنامه زمان‌بر شده یا اجرای آن بیش از اندازه کند شده است، آن‌گاه باید به سراغ بررسی مشکل مموری لیک بروید. چگونه متوجه شویم که برنامه‌ای که توسعه داده‌ایم مموری لیک دارد؟ یک علامت رایج آن استثناء java.lang.OutOfMemoryError است. این خطا به شما کمک می‌کند تا تشخیص دهید آیا نشتی حافظه وجود دارد یا خیر:

Java heap space: این پیام نشان می‌دهد که اندازه حافظه heap جاوا برای استفاده فعلی کافی نیست و منابع حافظه را نمی‌توان به یک شی خاص در حافظه heap جاوا اختصاص داد. Java Heap ناحیه‌ای از حافظه است که برای ذخیره اشیاء نمونه‌سازی شده توسط برنامه‌های کاربردی در ماشین مجازی استفاده می‌شود. هنگامی‌که ماشین مجازی جاوا راه‌اندازی می‌شود، حافظه heap ساخته می‌شود و مادامی‌که برنامه در حال اجرا است، هر شیء موجود در heap را می‌توان میان ریسمان‌ها به اشتراک گذاشت. اندازه heap می‌تواند متفاوت باشد، به همین دلیل برخی از توسعه‌دهندگان اندازه این ناحیه از حافظه را به ۲ تا ۸ گیگابایت محدود می‌کنند تا مکانیزم Garbage Collection با تاخیر کمتری انجام شود. این پیغام خطا می‌تواند بیان‌گر مموری لیک، کوچک بودن اندازه heap تعیین شده نسبت به نیازهای برنامه یا استفاده بیش از اندازه از finalizerها در برنامه کاربردی باشد.

فضای PermGen: فضای خالی در دسترس وجود ندارد. این ناحیه محل ذخیره متد و اشیاء کلاس است. می‌توانید با افزایش فضا از طریق  XX:MaxPermSize این مشکل را برطرف کنید. 

اندازه آرایه درخواستی از حد مجاز VM تجاوز می‌کند: برنامه سعی می‌کند آرایه‌ای را اختصاص دهد که بزرگ‌تر از اندازه heap است. 

Request <size> bytes for <reason>. Out of swap space:  تخصیص با استفاده از heap محلی موفقیت‌آمیز نبود، یا heap بومی رو به اتمام است.

<Reason> <stack trace> (Native method): یک متد بومی حافظه مورد نیاز را اختصاص نداده است.

نشت حافظه کمتر رایج

گاهی اوقات برنامه کاربردی، بدون نمایش پیام OutOfMemoryError از کار می‌افتد، به‌طوری که فرآیند شناسایی مموری لیک و انجام اقدامات اصلاحی را سخت می‌کند. برای این مشکل راهکاری وجود دارد. شما می‌توانید فایل‌های گزارش fatal log error یا crash dump را برای بررسی این موضوع که چه مشکلی به وجود آمده بررسی کنید. 

علاوه بر این، ابزارهای نظارتی و تشخیصی زیادی وجود دارد که می‌توانید برای شناسایی و تصحیح مموری لیک از آن‌ها استفاده کنید. دارین هاوارد (Darin Howard) از سایت Stackify، بر این باور است که Java profilers راهی عالی برای ردیابی مموری لیک و اجرای دستی مکانیزم Garbage Collector است. توسعه‌دهندگان می‌توانند از مکانیزم فوق برای بررسی نحوه استفاده از حافظه استفاده کنند و به راحتی فرآیندها و کلاس‌هایی که استفاده بیش از اندازه از حافظه دارند را شناسایی کنند. همچنین، می‌توانید از معیارهای عملکردی ماشین مجازی جاوا استفاده کنید که اطلاعاتی زیادی در مورد جمع‌آوری زباله، تعداد ریسمان‌ها و نحوه استفاده از حافظه در اختیارتان قرار می‌دهند. 

👈 بیشتر بدانید: آشنایی با تفاوت میان ClassNotFoundException و NoClassDefFoundError در جاوا

توضیحی کوتاه در ارتباط با نمایه‌های جاوا (Java profilers)

Java profilers به شما کمک می‌کنند بر پارامترهای مختلف ماشین مجازی جاوا، مثل ایجاد شی، اجرای ریسمان، اجرای متد و جمع‌‌آوری زباله نظارت کنید.

اگر بر این باور هستید که علت کندی عملکرد برنامه مموری لیک نیست، از Java profilers استفاده کنید تا نگاه عمیق‌تری به نحوه استفاده برنامه از حافظه و سایر منابع داشته باشید. به جای مرور کد‌های برنامه که فرآیند زمان‌بری است، از این ابزارها برای صرفه‌جویی در زمان استفاده کنید.

Java profilers طیف گسترده‌ای از اطلاعات کاربردی و آماری در اختیارتان قرار می‌دهند که می‌توانید از آن‌ها برای ردیابی اشتباهات کدنویسی خود استفاده کنید. نمایه‌ها، به شما کمک می‌کنند تا آن‌چه را که باعث کندی عملکرد، مشکلات چند ریسمانی و مموری لیک می‌شود را پیدا کنید. به طور خلاصه، Java profilers کمک می‌کنند یک برنامه پایدارتر و مقیاس‌پذیر طراحی کنید. بهترین بخش داستان این است که ابزارهای مذکور به شما کمک می‌کنند تا تجزیه و تحلیل دقیقی در ارتباط با مشکلات انجام دهید و راه‌حل کارآمدی برای آن‌ها ابداع کنید. 

سنجه‌های نمایه‌سازی جاوا (Java Profiling Metrics)

اگر از این ابزارها در مراحل اولیه پروژه و به طور منظم و به ویژه در ارتباط با سایر ابزارهای عملکردی جاوا استفاده کنید، شانس طراحی برنامه‌های کارآمد، با کارایی بالا، سریع و پایدار دوچندان می‌شود. ابزارهای مذکور به شما کمک می‌کنند تا قبل از استقرار برنامه خود، مسائل مهم را ارزیابی کنید. برخی از سنجه‌هایی که می‌توانید با استفاده از Java profiling جاوا به آن‌ها دست پیدا کنید به شرح زیر هستند: 

  • مدت زمان مصرفی که یک متد از پردازنده مرکزی استفاده کرده است. 
  • میزان استفاده از حافظه.
  • دستیابی به اطلاعاتی در مورد نحوه فراخوانی متد. 
  • چه اشیایی ایجاد شده‌اند. 
  • چه اشیایی از حافظه حذف شده‌اند.

تحلیل‌گر حافظه نمایه‌ساز جاوا MAT سرنام Java Profiler Memory Analyzer: به شما این امکان را می‌دهد با تحلیل heap data میزان استفاده از حافظه را به کمترین میزان برسانید. شما می‌توانید heap dumps را به ساده‌ترین شکل تحلیل کنید، حتا زمانی که میلیون‌ها شی فعال وجود دارند، اندازه هر شی و این‌که چرا garbage collector اشیاء خاصی را از حافظه حذف نمی‌کند را بررسی کنید. MAT گزارش دقیقی در مورد این اشیاء به شما می‌دهد و کمک می‌کند اگر مشکوک به مموری لیک هستید، این مشکل را برطرف کنید. 

Java Flight Recorder: یک ابزار تشخیصی و پروفایل است که اطلاعات بیشتری در مورد یک برنامه کاربردی در حال اجرا ارائه می‌کند و در بیشتر موارد نسبت به ابزارهای مشابه گزارش‌های دقیق‌تری ارائه می‌کند. Java Flight Recorder اجازه می‌دهد، واسط‌های برنامه نویسی کاربردی (API) توسط اشخاص ثالث ایجاد شوند و به این شکل هزینه کل مالکیت کمتر شود. یکی از ویژگی‌های تجاری Oracle Java SE، Java Flight Recorder ارائه راهکاری ساده برای تشخیص مموری لیک، پیدا کردن کلاس‌های عامل بروز مشکل و یافتن محل نشت است تا به سرعت مشکل را برطرف کنید. 

ابزارهای دیگری که باید از وجود آن‌ها مطلع باشید! 

NetBeans Profiler: از Java SE، Java FX، EJB، برنامه‌های کاربردی موبایل و برنامه‌های کاربردی وب پشتیبانی می‌کند و می‌تواند برای نظارت بر حافظه، ریسمان‌ها و منابع پردازنده مرکزی استفاده شود.

JProfiler: یک ابزار مرتبط با ریسمان‌ها، حافظه و پردازنده مرکزی است که می‌تواند برای تجزیه و تحلیل مموری لیک و سایر تنگناهای عملکردی استفاده شود.

GC Viewer:  یک ابزار منبع باز است که به شما امکان می‌دهد اطلاعات تولید شده توسط ماشین مجازی جاوا را مصورسازی کنید. شما می‌توانید از GC Viewer برای مشاهده معیارهای عملکردی مربوط به جمع‌آوری زباله، از جمله حالت‌های انتظار مکرر، طولانی‌ترین انتظارها و غیره استفاده کنید. علاوه بر این شما را قادر می‌سازد، مکانیزم جمع آوری زباله را اجرا کنید. شما می‌توانید از این ابزار برای تنظیم اندازه اولیه Heap نیز استفاده کنید.

VisualVM: مبتنی بر پلتفرم NetBeans است. VisualVM ابزاری توسعه‌پذیر است که از پلاگین‌های مختلف استفاده می‌کند تا اطلاعات دقیقی در مورد برنامه‌های کاربردی به دست آورید و فرآیند نظارت از راه دور یا محلی بر برنامه‌های کاربردی را اعمال کنید.. با استفاده از این ابزار می‌توانید از پروفایل حافظه استفاده کنید و به صورت دستی مکانیزم جمع‌آوری زباله را اجرا کنید.

Patty in action: ابزار منبع باز دیگری است که می‌توانید از آن به عنوان ابزاری برای نمایه‌سازی استفاده کنید تا پروفایل‌های هدفمند و دقیق به دست آورید. شما می‌توانید از این ابزار برای تجزیه و تحلیل heaps استفاده کنید.

JRockit: یک راه‌حل اختصاصی از شرکت اوراکل است. JRockit برای برنامه‌های Java SE طراحی شده و برای پیش‌بینی تأخیر، مصورسازی جمع‌آوری زباله و مسائل مربوط به حافظه استفاده می‌شود.

GCeasy: ابزاری است که گزارش‌های مربوط به جمع‌آوری زباله را تجزیه و تحلیل می‌کند و راهی ساده برای تشخیص مشکلات مموری لیک هنگام تجزیه و تحلیل گزارش‌های جمع‌آوری زباله ارائه می‌کند. GCeasy به صورت آنلاین در دسترس و قابل استفاده است و بنابراین برای استفاده از آن نیازی به نصب آن روی دستگاه هدف نیست.

مموری لیک جاوا: راه‌حل‌ها

اکنون که می‌دانید مموری لیک چیست و حدس می‌زنید که برنامه شما مموری لیک دارد، می‌توانید از این ابزارها برای رفع نشتی‌ها و قبل از آن‌که به یک مشکل حاد تبدیل شوند استفاده کنید. 

به کارگیری ابزارهایی که می‌توانند مموری لیک را تشخیص دهند!

برای آشنایی خوانندگان، قصد داریم از VisualVM استفاده کنیم.

هنگامی که VisualVM را دانلود و پیکربندی کردید، با اجرای برنامه خود با VisualVM متصل به آن، فرآیند تجزیه و تحلیل کدها را آغاز کنید. هنگامی که فرآیند یا کاری که باعث کندی برنامه شما می‌شود، اجرا می‌شود در ابزار VisualVM به برگه‌های "monitor" و "memory pools" نگاه کنید. باید به فکر اصلاح چه چیزی باشید؟ هنگامی که در زبانه monitor افزایش مصرف حافظه را مشاهده می‌کنید، دکمه "Perform GC" را فشار دهید تا مکانیزم جمع آوری زباله فعال شود. رویکرد فوق به کاهش میزان مصرف حافظه کمک می‌کند.

اگر راه‌حل فوق کار نکرد، به «memory pools» بروید و به بخش Old Gen نگاه کنید. اگر اشیا با مشکل نشت روبرو هستند، در این بخش قابل مشاهده هستند. به یاد داشته باشید که اشیاء فعال در "Eden" قرار می‌گیرند و سپس به "Survivor" منتقل می‌شوند. اشیاء قدیمی‌تر در مخزن "Old Gen" یافت می‌شوند.

در این مرحله، می‌توانید به کد خود بازگردید و بخش‌هایی که مشکل دارند را اصلاح کنید یا توضیحاتی در این بخش‌ها درج کنید. فرآیند ویرایش کدها را تا جایی که عملکرد بهبود پیدا کند ادامه دهید. تمام مراحل یاد شده را تا زمانی که تمام نشتی‌ها برطرف شوند، تکرار کنید.

برخی از بخش‌های کدهای‌تان را برای بررسی میزان استفاده از حافظه بررسی کنید و اگر نشت دیگری پیدا کردید، متدی که باعث این نشتی‌ها شده را پیدا کرده و آن‌را ویرایش کنید. این‌کار مادامی که ارزیابی کدها محدود به یک کلاس یا متد شوند باید انجام شود. تمام بافرهای فایل را اعتبارسنجی کنید تا ببینید بسته شده‌اند یا خیر. همچنین، تمامی hashmaps را بررسی کنید تا اطمینان حاصل کنید که بدون مشکل از آن‌ها استفاده می‌کنید. 

به کارگیری heap dumps

اگر روشی که اشاره کردیم، خسته‌کننده است، این شانس را دارید تا زمانی که برای رفع نشتی حافظه اختصاص می‌دهید را با استفاده از heap dumps کاهش دهید. Heap dumps به شما اجازه می‌دهد تعداد نمونه‌های باز شده و این‌که این نمونه‌ها چقدر فضا اشغال می‌کنند را مشاهده کنید. اگر نمونه خاصی وجود دارد که نیازمند ارزیابی بیشتر است، کافی است روی آن نمونه خاص دوبار کلیک کنید تا اطلاعات فنی دقیق‌تری به دست آورید. Heap dumps کمک می‌کند تا متوجه شوید چه تعداد شی توسط برنامه شما ساخته شده است. 

استفاده از هشدارهای نشت حافظه Eclipse

راه دیگر صرفه‌جویی در زمان، به کارگیری هشدارهای نشت حافظه Eclipse است. اگر کدی مطابق با JDK 1.5 یا بالاتر دارید، می‌توانید از Eclipse برای هشداردهی زمانی که یک مرجع پایان می‌یابد، اما شی همچنان باقی مانده و بسته نشده، استفاده کنید. اطمینان حاصل کنید که شناسایی نشت در تنظیمات پروژه فعال شده باشد. البته استفاده از Eclipse راه‌حل جامعی نیست، زیرا اکلیپس همه نشت‌ها را شناسایی نمی‌کند و ممکن است برخی از آن‌ها در برنامه وجود داشته باشند و از آن‌ها عبور کند، مخصوصاً زمانی که کدی دارید که با JDK 1.5 (یا بالاتر) سازگار نیست. یکی دیگر از دلایلی که اکلیپس همیشه خوب کار نمی‌کند این است که بسته و باز شدن فایل کلوژرها به شکل عمیق و تودرتو انجام می‌شود.

از بهترین نوشته‌های کاربران سکان آکادمی در سکان پلاس


online-support-icon