معرفی بازرس حافظه

کیم آنه تران
Kim-Anh Tran

این مقاله به معرفی Memory Inspector که در Chrome 91 فرود آمده است می‌پردازد. به شما امکان می‌دهد ArrayBuffer، TypedArray، DataView و Wasm Memory خود را بررسی کنید.

مقدمه

آیا تا به حال خواسته اید داده های موجود در ArrayBuffer خود را درک کنید؟ قبل از Memory Inspector، DevTools فقط بینش محدودی از ArrayBuffers را مجاز می دانست. بازرسی از نمای Scope در طول جلسه اشکال زدایی به مشاهده لیستی از مقادیر منفرد در بافر آرایه محدود می شد که درک کل داده ها را دشوار می کرد. به عنوان مثال، نمای Scope در مثال زیر بافر را به عنوان محدوده های قابل گسترش آرایه ها نشان می دهد:

نمای محدوده در DevTools

پیمایش به محدوده خاصی در بافر یک نقطه دردناک بود و کاربر را ملزم می کرد که به پایین اسکرول کند تا در نهایت به آن شاخص برسد. اما حتی اگر پیمایش به یک موقعیت آسان باشد، این روش بازرسی واقعی مقادیر دست و پا گیر است: تشخیص معنای این اعداد دشوار است. به خصوص، اگر آنها نباید به عنوان بایت های تک تفسیر شوند، اما به عنوان مثال به عنوان اعداد صحیح 32 بیتی تفسیر شوند، چه؟

بازرسی مقادیر با استفاده از Memory Inspector

بازرس حافظه

با کروم 91 ما Memory Inspector را معرفی می کنیم، ابزاری برای بررسی بافرهای آرایه. ممکن است قبلاً ابزارهای بازرسی حافظه برای مشاهده داده‌های باینری را دیده باشید که محتوای باینری را در یک شبکه به همراه آدرس‌هایشان نشان می‌دهند و راه‌های مختلفی برای تفسیر مقادیر زیربنایی ارائه می‌دهند. این چیزی است که بازرس حافظه برای شما آورده است. با Memory Inspector اکنون می توانید محتوا را مشاهده کنید، در آن پیمایش کنید، و انواعی را که برای تفسیر مقادیر در دست استفاده می شود انتخاب کنید. مقادیر ASCII را مستقیماً در کنار بایت ها نشان می دهد و به کاربر اجازه می دهد تا endianness های مختلف را انتخاب کند. بازرس حافظه را در عمل در زیر ببینید:

می خواهید آن را امتحان کنید؟ برای یادگیری نحوه باز کردن Memory Inspector و مشاهده بافر آرایه (یا TypedArray، DataView یا Wasm Memory) و اطلاعات بیشتر در مورد نحوه استفاده از آن، به مستندات ما در Memory Inspector مراجعه کنید. این نمونه های اسباب بازی (برای JS، Wasm و C++) را امتحان کنید.

طراحی بازرس حافظه

در این قسمت نگاهی به نحوه طراحی Memory Inspector با استفاده از Web Components خواهیم داشت و یکی از اهداف طراحی که داشتیم و نحوه پیاده سازی آن را نشان خواهیم داد. اگر کنجکاو هستید و می خواهید بیشتر ببینید، به سند طراحی ما برای بازرس حافظه نگاهی بیندازید.

ممکن است پست وبلاگ ما را در مورد مهاجرت به اجزای وب مشاهده کرده باشید، جایی که جک راهنمای داخلی ما را در مورد نحوه ساخت اجزای رابط کاربری با استفاده از اجزای وب منتشر کرده است. انتقال به Web Components با کار ما روی Memory Inspector همزمان شد و در نتیجه تصمیم گرفتیم سیستم جدید را امتحان کنیم. در زیر نموداری وجود دارد که اجزایی را که برای ایجاد Memory Inspector ساخته‌ایم نشان می‌دهد (توجه داشته باشید که در داخل آن را Linear Memory Inspector می‌نامیم):

اجزای وب

کامپوننت LinearMemoryInspector مولفه والد است که اجزای فرعی را ترکیب می کند که همه عناصر را در Memory Inspector ایجاد می کند. اساساً یک Uint8Array و یک address می گیرد، و با هر تغییر هر کدام، داده ها را به فرزندان خود منتشر می کند، که باعث رندر مجدد می شود. خود LinearMemoryInspector سه جزء فرعی را ارائه می دهد:

  1. LinearMemoryViewer (نمایش مقادیر)،
  2. LinearMemoryNavigator (که به ناوبری اجازه می دهد) و
  3. LinearMemoryValueInterpreter (نمایش تفاسیر نوع مختلف از داده های اساسی).

دومی خود یک مؤلفه والد است که ValueInterpreterDisplay (نمایش مقادیر) و ValueInterpreterSettings (انتخاب نوع هایی که در صفحه نمایش دیده شود) را رندر می کند.

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

نمودار اجزاء

LinearMemoryInspector خود را به عنوان شنونده در LinearMemoryNavigator اضافه می کند. تابع addressChanged باید در رویداد address-changed فعال شود. به محض اینکه کاربر اکنون ورودی آدرس را ویرایش می کند، رویداد فوق الذکر را ارسال می کند، به طوری که تابع addressChanged فراخوانی می شود. این تابع اکنون آدرس را به صورت داخلی ذخیره می کند و اجزای فرعی آن را با استفاده از تنظیم کننده data(address, ..) به روز می کند. اجزای فرعی آدرس را به صورت داخلی ذخیره می کنند و نماهای خود را مجدداً ارائه می دهند و محتوا را در آن آدرس خاص نشان می دهند.

هدف طراحی: مستقل کردن عملکرد و مصرف حافظه از اندازه بافر

یکی از جنبه های طراحی Memory Inspector که در نظر داشتیم این بود که عملکرد Memory Inspector باید مستقل از اندازه بافر باشد.

همانطور که در قسمت قبل مشاهده کردید، مؤلفه LinearMemoryInspector یک UInt8Array را برای ارائه مقادیر می گیرد. در همان زمان، می‌خواستیم مطمئن شویم که بازرس حافظه نیازی به نگه داشتن کل داده‌ها ندارد، زیرا بازرس حافظه تنها بخشی از آن را نشان می‌دهد (مثلاً حافظه Wasm می‌تواند به اندازه 4 گیگابایت باشد، و ما نمی‌خواهیم برای ذخیره 4 گیگابایت در Memory Inspector).

بنابراین برای اطمینان از اینکه سرعت و مصرف حافظه Memory Inspector مستقل از بافر واقعی است که نشان می‌دهیم، به مؤلفه LinearMemoryInspector اجازه می‌دهیم فقط زیر محدوده‌ای از بافر اصلی را نگه دارد.

برای این کار، LinearMemoryInspector ابتدا نیاز به دو آرگومان دیگر دارد: memoryOffset و outerMemoryLength . memoryOffset نشان دهنده آفست است که در آن Uint8Array ارسال شده شروع می شود و برای ارائه آدرس های داده صحیح لازم است. outerMemoryLength طول بافر اصلی است و برای درک اینکه چه محدوده ای را می توانیم نشان دهیم لازم است:

بافر

با این اطلاعات می‌توانیم اطمینان حاصل کنیم که همچنان می‌توانیم همان نمای قبلی (محتوای اطراف address ) را ارائه کنیم، بدون اینکه در واقع همه داده‌ها را در جای خود داشته باشیم. بنابراین اگر آدرس دیگری درخواست شود که در محدوده متفاوتی قرار می گیرد، چه باید کرد؟ در آن صورت، LinearMemoryInspector یک RequestMemoryEvent راه‌اندازی می‌کند، که محدوده فعلی را که حفظ می‌شود به‌روزرسانی می‌کند. یک مثال در زیر نشان داده شده است:

نمودار جریان ماشه رویداد

در این مثال، کاربر صفحه حافظه را پیمایش می‌کند (بازرس حافظه از صفحه‌بندی برای نمایش تکه‌های داده استفاده می‌کند)، که یک PageNavigationEvent را راه‌اندازی می‌کند، که خود یک RequestMemoryEvent راه‌اندازی می‌کند. این رویداد واکشی محدوده جدید را آغاز می کند، که سپس از طریق تنظیم داده ها به مؤلفه LinearMemoryInspector منتشر می شود. در نتیجه، داده‌های تازه واکشی شده را نشان می‌دهیم.

اوه، و آیا می دانستید؟ حتی می توانید حافظه را در کد Wasm و C/C++ بررسی کنید

Memory Inspector نه تنها برای ArrayBuffers در جاوا اسکریپت در دسترس است، بلکه می تواند برای بازرسی حافظه Wasm و حافظه اشاره شده توسط مراجع/اشاره گرهای C/C++ نیز استفاده شود (با استفاده از پسوند DWARF ما - اگر هنوز این کار را نکرده اید، آن را امتحان کنید! اشکال زدایی WebAssembly با ابزارهای مدرن را در اینجا مشاهده کنید.

حافظه را در C++ بررسی کنید

نتیجه گیری

این مقاله Memory Inspector را ارائه کرد و نمایی از طراحی آن را نشان داد. ما امیدواریم که Memory Inspector به شما کمک کند تا متوجه شوید در ArrayBuffer شما چه اتفاقی می افتد :-). اگر پیشنهادی برای بهبود آن دارید به ما اطلاع دهید و یک اشکال را ثبت کنید !

کانال های پیش نمایش را دانلود کنید

استفاده از Chrome Canary ، Dev یا Beta را به عنوان مرورگر توسعه پیش‌فرض خود در نظر بگیرید. این کانال‌های پیش‌نمایش به شما امکان دسترسی به جدیدترین ویژگی‌های DevTools را می‌دهند، به شما اجازه می‌دهند APIهای پلتفرم وب پیشرفته را آزمایش کنید و به شما کمک می‌کنند تا قبل از کاربران، مشکلات سایت خود را پیدا کنید!

با تیم Chrome DevTools در تماس باشید

از گزینه‌های زیر برای بحث در مورد ویژگی‌های جدید، به‌روزرسانی‌ها یا هر چیز دیگری مربوط به DevTools استفاده کنید.