การตรวจจับ/การบันทึก AS3 หยุดโลก GC หยุดชั่วคราว

บริบท: แอปพลิเคชัน AS3 ขนาดใหญ่ที่อาจประสบปัญหาการหยุดการเก็บขยะ "หยุดโลก" บ่อยครั้งแต่ไม่อาจคาดเดาได้หยุดชั่วคราว เมื่อมีใครโจมตี อาจต้องใช้เวลา 30 วินาทีขึ้นไปจึงจะสรุปได้

สิ่งนี้ไม่ได้เกิดขึ้นในการทดสอบ แต่อาจเกิดขึ้นในการใช้งานจริง

คำถาม: มีการบันทึกจาก Flash VM ที่อาจใช้ในการตรวจจับและบันทึกเหตุการณ์ดังกล่าวหรือไม่ ฉันกำลังรวบรวมประสบการณ์ของฉันกับ Java ที่นี่ ฉันได้อ่านมาอย่างกว้างขวางเกี่ยวกับการทำงานของเครื่องจักร Flash GC (การนับอ้างอิงด้วยการทำเครื่องหมาย/การกวาด) แต่ฉันกำลังมองหาการวัดและส่งข้อมูลทางไกลที่แท้จริงจากแอปพลิเคชันที่ทำงานในป่า เนื่องจากฉันเข้าใจว่าเหตุการณ์ GC การทำเครื่องหมาย/การกวาดสามารถ " หยุดโลก".


person Martin Cowie    schedule 26.08.2014    source แหล่งที่มา
comment
ไม่ใช่ความผิดของ GC แต่เป็นของคุณ มีการสร้างออบเจ็กต์มากเกินไป และไม่มีวิธีที่ถูกต้องในการรับ GC ใช้การรวมกลุ่มหรือสร้างวัตถุน้อยลง   -  person BotMaster    schedule 27.08.2014
comment
คุณเข้าใจผิด. ฉันพยายามที่จะสร้าง หาก การหยุดชั่วคราวที่สังเกตนั้นเกิดจาก GC   -  person Martin Cowie    schedule 27.08.2014


คำตอบ (4)


คุณถูก. ตัวรวบรวมขยะหยุดการทำงานของแอปพลิเคชันชั่วคราว

อัลกอริธึมตัวรวบรวมขยะ Flash Runtime ทำงานเพิ่มขึ้นในขณะที่ทำเครื่องหมายหน่วยความจำที่ใช้งานอยู่ มันหยุดการทำงานของแอพพลิเคชั่นชั่วคราวเมื่อรวบรวมหน่วยความจำส่วนที่ไม่ได้ใช้ การหยุดชั่วคราวที่เกิดขึ้นเมื่อรอบการรวบรวมที่เพิ่มขึ้นเสร็จสิ้นอาจยาวนานกว่าที่ต้องการ และสามารถสังเกตหรือได้ยินได้ในบางโปรแกรม

จาก ข้อมูลอ้างอิง

ตรวจสอบว่าตัวรวบรวมขยะทำงานหรือไม่

ตามความรู้ของฉัน ไม่มีวิธีโดยตรงที่จะทราบได้ว่า GC วิ่งอยู่หรือไม่ แต่เป็นไปได้ที่จะให้ฟังก์ชันทดสอบดำเนินการบน ENTER_FRAME และตรวจสอบว่ามีการรวบรวมขยะนับตั้งแต่การเรียกใช้ฟังก์ชันครั้งล่าสุดหรือไม่ อย่างมีประสิทธิภาพตั้งแต่เฟรมที่แล้ว

ด้วย Dictionary ซึ่งสามารถจัดเก็บคีย์อ้างอิงที่ไม่รัดกุม คุณสามารถดูได้ว่ามีการรวบรวมออบเจ็กต์หรือไม่ หากเป็นกรณีนี้ การรวบรวมขยะจะต้องดำเนินการ ในคลาสต่อไปนี้ ฉันสร้างอ็อบเจ็กต์ใหม่ เพื่อตรวจสอบในภายหลังว่ามีการรวบรวมหรือไม่

package
{
    import flash.display.Sprite;
    import flash.utils.Dictionary;

    public class GCTest
    {
        private static var dict:Dictionary = null;
        
        public static function didGCRun():Boolean
        {
            if ( dict == null ) {
                dict = new Dictionary(true);
            }
            
            var hasKeys:Boolean = false;
            
            for ( var obj:* in dict ) {
                hasKeys = true;
                break;
            }
            
            if ( hasKeys ) {
                return false;
            }
            else {
                dict[new Sprite()] = null;
                return true;
            }
        }       
    }
}    

โดยการตรวจสอบในแต่ละเฟรม คุณจะรู้ว่า gc stroke หรือไม่

addEventListener(Event.ENTER_FRAME, onEnterFrame);

private function onEnterFrame(event:Event):void
{
    var gcRan:Boolean = GCTest.didGCRun();
}

การใช้ความจำ

คุณยังสามารถตรวจสอบการรวบรวมขยะโดยตรวจสอบการใช้หน่วยความจำ เอกสารแนะนำให้ใช้ System.freeMemory()

จำนวนหน่วยความจำ (เป็นไบต์) ที่จัดสรรให้กับ Adobe Flash Player หรือ Adobe AIR และที่ไม่ได้ใช้งาน ส่วนที่ไม่ได้ใช้ของหน่วยความจำที่จัดสรร (System.totalMemory) จะผันผวนเมื่อมีการรวบรวมขยะ ใช้คุณสมบัตินี้เพื่อตรวจสอบการรวบรวมขยะ

ฉันจะใช้ค่านี้ร่วมกับ System.totalMemoryNumber()

ตรวจสอบเวลาดำเนินการ

เมื่อใช้ร่วมกับวิธีอื่นๆ การบันทึกอัตราเฟรมจริงหรือเวลาดำเนินการของบล็อกโค้ดอาจเป็นประโยชน์ ซึ่งสามารถทำได้โดยการจัดเก็บสถานะการออนไลน์ของโปรแกรมไว้ในตัวแปรและเปรียบเทียบในภายหลัง

ใช้ getTimer()

สำหรับการประมวลผลรันไทม์ Flash ActionScript 3.0 เมธอดนี้จะส่งคืนจำนวนมิลลิวินาทีที่ผ่านไปนับตั้งแต่เครื่องเสมือนรันไทม์ Flash สำหรับ ActionScript 3.0 (AVM2) เริ่มทำงาน

var startTime:int = getTimer();
// execution or frame change
var executionTime:int = getTimer() - startTime;

เมื่อใช้กับแต่ละเฟรม คุณสามารถเปรียบเทียบสิ่งนี้กับ stage.frameRate และตรวจสอบความคลาดเคลื่อน

แนะนำให้ผู้รวบรวมขยะดำเนินการ

ความเป็นไปได้ที่จะลดการหยุดชั่วคราวของคุณอาจเป็นการแนะนำให้ผู้รวบรวมขยะดำเนินการด้วยตนเอง System.pauseForGCIfCollectionImminent(imminence:Number = 0.75) จะ หยุดการทำงานของโปรแกรมชั่วคราวหากความใกล้เข้ามาจริงสูงกว่าค่าอาร์กิวเมนต์

ความใกล้เข้ามานั้นหมายถึงระยะที่นักสะสมเชื่อว่ามันผ่านไปได้มากเพียงใด และด้วยเหตุนี้ความใกล้จะกระตุ้นให้เกิดการหยุดคอลเลกชันชั่วคราว อาร์กิวเมนต์ความใกล้เข้ามาของฟังก์ชันนี้คือขีดจำกัด: ตัวรวบรวมขยะจะถูกเรียกใช้เฉพาะเมื่อความใกล้เข้ามาจริงเกินค่าขีดจำกัด มิฉะนั้น สายนี้จะโทรกลับทันทีโดยไม่ดำเนินการใดๆ

โดยการเรียกใช้ฟังก์ชันนี้ด้วยค่าความใกล้เคียงต่ำ แอปพลิเคชันจะระบุว่ายินดีที่จะยอมรับว่าการมาร์กจำนวนค่อนข้างมากจะต้องเสร็จสิ้น ในทางกลับกัน ค่าความใกล้เคียงที่สูงบ่งชี้ว่าควรหยุดการใช้งานชั่วคราวเฉพาะในกรณีที่การมาร์กใกล้จะเสร็จสมบูรณ์เท่านั้น โดยปกติแล้ว การหยุดชั่วคราวจะนานกว่าในกรณีหลัง

ใกล้เข้ามา:ตัวเลข (ค่าเริ่มต้น = 0.75) — ตัวเลขระหว่าง 0 ถึง 1 โดยที่ 0 หมายถึงใกล้เข้ามาน้อยกว่า และ 1 หมายถึงใกล้เข้ามามากที่สุด ค่าที่น้อยกว่า 0 มีค่าเริ่มต้นเป็น 0.25 ค่าที่มากกว่า 1.0 จะมีค่าเริ่มต้นเป็น 1.0 NaN มีค่าเริ่มต้นอยู่ที่ 0.75

จาก ข้อมูลอ้างอิง

person dreamlab    schedule 03.09.2014

Adobe Scout เป็นเครื่องมือที่ดีในการจัดทำโปรไฟล์โครงการ AS3

person C. Parcell    schedule 26.08.2014
comment
ปัญหาเกิดขึ้นเฉพาะในที่ที่การใช้ Scout ไม่สามารถทำได้ - น่าเศร้า - person Martin Cowie; 26.08.2014
comment
.. เป็นไปได้ไหมที่จะส่งออกไฟล์การวัดและส่งข้อมูลทางไกลของ Scout จากแอปพลิเคชันที่ทำงานอยู่ ในสถานการณ์เช่นนี้ - person Martin Cowie; 27.08.2014
comment
Scout จะตรวจจับโดยอัตโนมัติเมื่อคุณเปิดแอป AIR หรือ SWF ในเบราว์เซอร์ ดังนั้นจึงเป็นไปได้ที่จะดูข้อมูลการวัดและส่งข้อมูลทางไกลแบบเรียลไทม์จากแอปคุณภาพที่เปิดตัว แม้ว่าในการรับข้อมูลการวัดและส่งข้อมูลทางไกลแบบเต็ม คุณจะต้องคอมไพล์แอปโดยใช้ -advanced-telemetry=true แฟล็กคอมไพเลอร์ หรือประมวลผลไฟล์ SWF ที่คอมไพล์เพื่อรองรับการใช้ เครื่องมือนี้ - person Varnius; 27.08.2014
comment
Scout นั้นทรงพลังมากจริงๆ แม้ว่าคุณจะไม่สามารถสร้างการค้างเป็นเวลา 30 วินาทีได้ แต่ก็มีความเป็นไปได้สูงที่คุณจะพบปัญหาในการจัดสรรที่แอปพลิเคชันของคุณทำ มิฉะนั้นก็จะไม่มีปัญหาดังกล่าวกับ GC กิจกรรม GC ไม่ได้มาจากไหน การหยุดดังกล่าวต้องเกิดจากการจัดสรรจำนวนมาก - person jauboux; 05.09.2014

คุณสามารถใช้ได้ :

setInterval( function()
{
    trace(System.totalMemory);
},1000);

เมื่อใดก็ตามที่ตัวรวบรวมขยะทำงานและงานยุ่ง จำนวนหน่วยความจำจะเปลี่ยนแปลงไปมาก หากคุณเห็นการเปลี่ยนแปลงของหน่วยความจำและในเวลาเดียวกันโปรแกรมของคุณหยุดชั่วคราวหรือมีข้อบกพร่องซึ่งเกิดจาก GC

person Mehdi Golzadeh    schedule 02.09.2014

ก่อนอื่นเลย สภาพแวดล้อมการผลิตของคุณคืออะไร? เครื่องเล่นแฟลช, เดสก์ท็อป AIR, AIR มือถือ ? แอปของคุณควรจะทำงานด้านการคำนวณหนักๆ ใช่ไหม

การเก็บขยะนาน 30+ วินาทีดูเหมือนจะมาก แต่ถ้าการหยุดชั่วคราวเกิดจากคนเก็บขยะจริงๆ การบันทึกก็จะไม่ช่วยอะไรคุณมากนัก ยกเว้นการยืนยันข้อสันนิษฐานของคุณ

สิ่งแรกที่ฉันจะทำคือทดสอบแอปของคุณอย่างกว้างขวางด้วยการวัดและส่งข้อมูลทางไกล หากคุณเห็นสัญญาณของกิจกรรมที่ผิดปกติของ GC (หนามสีแดงขนาดใหญ่ หรือสัญญาณรบกวน gc ถาวรที่มากกว่าสองสามเปอร์เซ็นต์ในทุกเฟรม) ให้เปิดใช้งานหน่วยความจำ การวัดและส่งข้อมูลทางไกลของการจัดสรร และค้นหา/ขจัดปัญหาคอขวดในการสร้างอินสแตนซ์ของหน่วยความจำ เพียงจำไว้ว่าแม้แต่การจัดสรรที่ว่างก็มีผลกระทบต่อ gc ดังนั้นให้ใช้การรวมกลุ่ม และเข้มงวดมากกับการจัดสรรที่เกิดขึ้นในทุกเฟรม แม้แต่การจัดสรรเพียงเล็กน้อยก็มีผลกระทบอย่างมีนัยสำคัญ ระวังว่าการแยกวิเคราะห์ไฟล์ xml หรือ json ขนาดใหญ่นั้นมีน้ำหนักมากในการจัดสรร

เมื่อคุณแน่ใจว่าแอปพลิเคชันของคุณใช้หน่วยความจำอย่างถูกต้องแล้ว ให้ตรวจสอบ (หรือให้ผู้ทดสอบ/ผู้ทดสอบเบต้า/ผู้ใช้ตรวจสอบ) ว่าปัญหายังคงอยู่หรือไม่ หรือพบบ่อยน้อยลงหรือแม้กระทั่งหายไปแล้ว

หากไม่ได้ผล อย่างน้อยที่สุด คุณจะต้องปรับปรุงประสิทธิภาพและขนาดหน่วยความจำของแอปของคุณตั้งแต่แรก คุณไม่มีข้อมูลเพิ่มเติมเกี่ยวกับลักษณะของการหยุดชั่วคราว และคุณได้พิจารณาตัวเลือกอื่นนอกเหนือจาก GC หรือไม่ ปัญหาอาจไม่ได้อยู่ที่ที่คุณค้นหา: คุณสามารถลองจับและบันทึกข้อผิดพลาดทั้งหมดด้วย UncaughtErrorEvent (จากนั้นใช้ URLLoader เพื่อโพสต์กลุ่มข้อผิดพลาดไปยังบริการบันทึกข้อผิดพลาดของคุณ) สามารถช่วยให้คุณตรวจจับข้อผิดพลาดในการผลิตซ้ำได้ยาก เช่น:

  • ติดอยู่ในฟังก์ชัน: ควรโยน ScriptTimeoutError หลังจากผ่านไป 15 วินาที (รหัส #1502) ซึ่งจะเปิดป๊อปอัปในตัวดีบักเกอร์ของ Flash Player

  • ข้อผิดพลาดอื่นใดจะขัดจังหวะทั้งสแต็กซึ่งอาจทำให้แอปพลิเคชันของคุณอยู่ในสถานะไม่ตอบสนอง บางทีการหมดเวลานานอาจทำให้ตอบสนองได้อีกครั้ง

BTW คุณจะรู้ได้อย่างไรว่าแอปพลิเคชันของคุณค้างนานกว่า 30 วินาที หากคุณไม่ได้เข้าสู่ระบบและไม่เคยทำซ้ำเลย หากเป็นข้อผิดพลาดที่ผู้ใช้รายงาน ให้ลองรับข้อมูลเพิ่มเติม (รับระบบปฏิบัติการ เวอร์ชัน Flash Player รูปแบบ...) หากเกิดขึ้นบ่อยครั้ง คุณควรจะสามารถทำซ้ำได้

person jauboux    schedule 04.09.2014