যদি কোনও ডিওএম এলিমেন্ট সরানো হয় তবে এর শ্রোতারা কি স্মৃতি থেকে সরানো হয়?


উত্তর:


307

আধুনিক ব্রাউজারগুলি

সরল জাভাস্ক্রিপ্ট

যদি কোনও ডিওএম উপাদান মুছে ফেলা হয় তবে তা রেফারেন্স-মুক্ত (কোনও রেফারেন্সই এটি নির্দেশ করে না) তবে হ্যাঁ - উপাদানটি নিজেই আবর্জনা সংগ্রহকারী এবং এর সাথে সম্পর্কিত কোনও ইভেন্ট হ্যান্ডলার / শ্রোতা দ্বারা তুলে নিয়েছে।

var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
b = null; 
// A reference to 'b' no longer exists 
// Therefore the element and any event listeners attached to it are removed.

যাহোক; যদি এখনও উল্লেখিত উপাদানগুলিতে নির্দেশিত রেফারেন্স থাকে তবে উপাদান এবং এর ইভেন্ট শ্রোতাদের স্মৃতিতে ধরে রাখা হয়।

var a = document.createElement('div');
var b = document.createElement('p'); 
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b); 
// A reference to 'b' still exists 
// Therefore the element and any associated event listeners are still retained.

jQuery এর

অনুমান করা ঠিক হবে যে jQuery সম্পর্কিত প্রাসঙ্গিক পদ্ধতিগুলি (যেমন remove()) ঠিক একই পদ্ধতিতে কাজ করবে ( উদাহরণস্বরূপ remove()ব্যবহার করে বিবেচনা করা হয়েছিল removeChild())।

তবে, এটি সত্য নয় ; jQuery লাইব্রেরিতে প্রকৃতপক্ষে একটি অভ্যন্তরীণ পদ্ধতি রয়েছে (যা নিঃশব্দে এবং তত্ত্বের যে কোনও সময় পরিবর্তন করা যেতে পারে) নামক cleanData() (এখানে এই পদ্ধতিটি দেখতে কেমন তা বোঝা যায় ) যা ডিওএম থেকে অপসারণের পরে কোনও উপাদান সম্পর্কিত সমস্ত ডেটা / ইভেন্টগুলি স্বয়ংক্রিয়ভাবে পরিষ্কার করে দেয় (এর মাধ্যমে হতে হবে। remove(), empty(), html("")ইত্যাদি)।


পুরানো ব্রাউজারগুলি

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

যদি আপনি লিগ্যাসি আই সংস্করণ মেমরি ফাঁস ঠিক করার জন্য ব্যবহৃত কারণগুলি, নিদর্শনগুলি এবং সমাধানগুলির আরও গভীরভাবে ব্যাখ্যা চান তবে আমি সম্পূর্ণরূপে আপনাকে সুপারিশ করব ইন্টারনেট এক্সপ্লোরার লিক প্যাটার্নগুলি বোঝার এবং সমাধানের উপর এই এমএসডিএন নিবন্ধটি পড়ুন

এটি সম্পর্কিত আরও কয়েকটি নিবন্ধ:

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


22
Jquery ডকুমেন্টেশন অনুসারে কোনও উপাদানের উপর মুছে ফেলা () পদ্ধতি ব্যবহার করার সময়, সমস্ত ইভেন্ট শ্রোতাদের স্মৃতি থেকে সরানো হয়। এটি সেল্ট উপাদান এবং সমস্ত শিশু নোডকে প্রভাবিত করে। আপনি যদি ইভেন্ট তালিকাগুলিকে মেমোরিতে রাখতে চান তবে আপনার পরিবর্তে .detach () ব্যবহার করা উচিত। মুছে ফেলা উপাদানগুলি আবার ডোমে sertedোকানো হতে পারে যখন দরকারী।
Lothre1

1
যদি উপাদানটিতে শিশু একাদশ থাকে তবে এটি কি শিশু উপাদানগুলিতে ইভেন্ট তালিকাগুলি আলাদা করে দেবে?
CBeTJlu4ok

1
@ লথ্রে 1 - কেবল তখনই removeপদ্ধতিটি ব্যবহার করার সময় । বেশিরভাগ সময় ডোম পুরোপুরি মুছে ফেলা হবে। (যেমন টার্বো লিঙ্ক বা কিছু)। আমি ভাবছি যদি আমি করি তবে স্মৃতি কীভাবে প্রভাবিত হয় document.body.innerHTML = ''...
vsync

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

1
@ লোথ্রে ১ ধন্যবাদ - আমি কিছুটা গভীর খনন করেছি এবং জানতে পেরেছি যে কীভাবে jQuery এই ক্ষেত্রে নিয়মিত জাভাস্ক্রিপ্ট থেকে আলাদাভাবে কাজ করে। উত্তর আপডেট করেছেন।
ডিসগ্রিফিন

23

jQuery সম্পর্কিত:

.remove () পদ্ধতিটি DOM এর বাইরে উপাদান নিয়ে যায়। আপনি যখন উপাদানটি নিজেই অপসারণ করতে চান, তেমনি এর অভ্যন্তরের সমস্ত কিছু .reove () ব্যবহার করুন। উপাদানগুলি এগুলি ছাড়াও, উপাদানগুলির সাথে সম্পর্কিত সমস্ত সীমাবদ্ধ ইভেন্ট এবং jQuery ডেটা সরানো হয়। ডেটা এবং ইভেন্টগুলি সরিয়ে না দিয়ে উপাদানগুলি সরাতে, পরিবর্তে .detach () ব্যবহার করুন।

তথ্যসূত্র: http://api.jquery.com/remove/

jQuery v1.8.2 .remove()উত্স কোড:

remove: function( selector, keepData ) {
    var elem,
        i = 0;

    for ( ; (elem = this[i]) != null; i++ ) {
        if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
            if ( !keepData && elem.nodeType === 1 ) {
                jQuery.cleanData( elem.getElementsByTagName("*") );
                jQuery.cleanData( [ elem ] );
            }

            if ( elem.parentNode ) {
                elem.parentNode.removeChild( elem );
            }
        }
    }

    return this;
}

স্পষ্টত jQuery ব্যবহার করে node.removeChild()

এটি অনুসারে: https://developer.mozilla.org/en-US/docs/DOM/Node.removeChild ,

The removed child node still exists in memory, but is no longer part of the DOM. You may reuse the removed node later in your code, via the oldChild object reference.

অর্থাত্ ইভেন্ট শ্রোতারা মুছে ফেলা হতে পারে, তবে nodeএখনও স্মৃতিতে বিদ্যমান।


3
আপনি কেবল বিভ্রান্তি যুক্ত করছেন - jQuery এমন কিছুই করেনি যা হ্যান্ডলারের সাথে সহজ removeChildনা করে। উভয়ই আপনাকে এমন একটি রেফারেন্স ফিরিয়ে দেয় যা আপনি উত্তরোত্তর পুনরায় সংযোগ রাখতে পারেন (যার ক্ষেত্রে এটি স্পষ্টত স্মৃতিতে থেকে যায়) বা নিক্ষেপ (যে ক্ষেত্রে এটি শেষ পর্যন্ত জিসি দ্বারা তুলে নিয়ে যায় এবং সরিয়ে দেওয়া হয়)।
ওলেগ ভি। ভলকভ

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

8

ইভেন্ট হ্যান্ডলারগুলিতে মেমোরি ফাঁস হওয়ার সাথে সংঘবদ্ধকরণের সাথে উপাদানটির একটি রেফারেন্স রাখা এবং ইভেন্ট হ্যান্ডলারের একটি রেফারেন্স রাখার জন্য গাদা দেখতে দ্বিধা করবেন না।

আবর্জনা সংগ্রাহক বিজ্ঞপ্তি উল্লেখ পছন্দ করেন না।

সাধারণ মেমরি ফাঁস কেস: স্বীকার করুন যে কোনও বস্তুর একটি উপাদানের একটি রেফ রয়েছে। এই উপাদানটির হ্যান্ডলারের একটি রেফ রয়েছে। এবং হ্যান্ডলারের একটি অবজেক্ট রয়েছে। অবজেক্টটিতে অন্যান্য অনেকগুলি অবজেক্ট রয়েছে। এই অবজেক্টটি আপনার সংগ্রহ থেকে অযৌক্তিক বিবেচনা করে আপনি ফেলে দিয়েছেন বলে আপনি মনে করেন এমন সংগ্রহের অংশ ছিল। => সম্পূর্ণ অবজেক্ট এবং এটি নির্দেশিত সমস্ত পৃষ্ঠা পৃষ্ঠা থেকে প্রস্থান না হওয়া অবধি স্মৃতিতে থাকবে। => আপনাকে নিজের অবজেক্ট শ্রেণির জন্য একটি সম্পূর্ণ হত্যা পদ্ধতি সম্পর্কে চিন্তা করতে হবে বা উদাহরণস্বরূপ একটি এমভিসি কাঠামোতে বিশ্বাস করতে হবে।

তদতিরিক্ত, ক্রোম দেব সরঞ্জামগুলির পুনরায় বর্ধিত অংশ ব্যবহার করতে দ্বিধা করবেন না।


8

কেবল অন্য উত্তরগুলি প্রসারিত করা হচ্ছে ...

প্রতিনিধি ইভেন্ট হ্যান্ডলারগুলি উপাদান অপসারণের পরে সরানো হবে না।

$('body').on('click', '#someEl', function (event){
  console.log(event);
});

$('#someEL').remove(); // removing the element from DOM

এখন যাচাই করুন:

$._data(document.body, 'events');

9
ইভেন্ট হ্যান্ডলারটি শরীরের সাথে সংযুক্ত থাকে এবং #SomeEl নয়, স্বাভাবিকভাবেই হ্যান্ডলারটি অপসারণ করা উচিত না যতক্ষণ শরীর এখানে থাকে still
ইয়াংশুন তায়ে

এই মুছে ফেলা হতে পারে নিজে: stackoverflow.com/questions/22400907/...
fangxing

7

সম্পর্কিত jQuery, নিম্নলিখিত সাধারণ পদ্ধতিগুলি ডেটা এবং ইভেন্ট হ্যান্ডলারগুলির মতো অন্য নির্মাণগুলিও সরিয়ে ফেলবে:

অপসারণ()

উপাদানগুলি এগুলি ছাড়াও, উপাদানগুলির সাথে সম্পর্কিত সমস্ত সীমাবদ্ধ ইভেন্ট এবং jQuery ডেটা সরানো হয়।

খালি ()

মেমোরি ফাঁস এড়াতে, jQuery অন্যান্য উপাদানগুলি যেমন উপাদানগুলি থেকে ইভেন্টগুলি হস্তান্তরকারীদের থেকে উপাদান এবং ইভেন্ট হ্যান্ডলারগুলি সরিয়ে দেয় s

এইচটিএমএল ()

অতিরিক্তভাবে, jQuery সেই উপাদানগুলিকে নতুন সামগ্রীতে প্রতিস্থাপন করার আগে শিশু উপাদানগুলি থেকে ডেটা এবং ইভেন্ট হ্যান্ডলারগুলির মতো অন্যান্য নির্মাণগুলি সরিয়ে দেয়।


2

হ্যাঁ, আবর্জনা সংগ্রহকারী তাদের এগুলিও সরিয়ে দেবে। লিগ্যাসি ব্রাউজারগুলির ক্ষেত্রে সর্বদা ক্ষেত্রে নাও হতে পারে।


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