จะยกเลิกการโหลด ByteArray โดยใช้ Actionscript 3 ได้อย่างไร


93

ฉันจะยกเลิกการโหลดByteArrayหน่วยความจำโดยใช้ ActionScript 3 ได้อย่างไร

ฉันได้ลองทำสิ่งต่อไปนี้แล้ว:

// First non-working solution
byteArray.length = 0;
byteArray = new ByteArray();

// Second non-working solution
for ( var i:int=0; i < byteArray.length; i++ ) {
    byteArray[i] = null;
}

คำตอบ:


35

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

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

ตามที่ฉันเข้าใจแล้วการจัดการหน่วยความจำในระบบปฏิบัติการสมัยใหม่ไม่ได้ใช้งานง่ายจากมุมมองของการดูจำนวนเงินที่จัดสรรให้กับแต่ละกระบวนการหรือแม้แต่จำนวนเงินทั้งหมดที่จัดสรร

เมื่อฉันใช้ Mac ของฉันเป็นเวลา 5 นาที 95% ของ RAM 3 GB ของฉันถูกใช้และมันจะยังคงอยู่อย่างนั้นมันไม่เคยลดลง นั่นเป็นเพียงวิธีที่ระบบปฏิบัติการจัดการกับหน่วยความจำ

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


25

(ฉันไม่คิดบวกเกี่ยวกับเรื่องนี้ แต่ ... )

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

สมมติว่าไม่มีการอ้างอิงอื่น ๆ ไปยังหน่วยความจำที่ชี้โดยbyteArrayหรือรายการภายในอาร์เรย์หน่วยความจำจะถูกปลดปล่อยในบางจุดหลังจากที่คุณออกจากขอบเขตที่byteArrayมีการประกาศ

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

ในการบังคับ GC ให้ลอง (ใช่สองครั้ง):

flash.system.System.gc();
flash.system.System.gc();

คุณสามารถอ่านเพิ่มเติมได้ที่นี่


20

ลองดูบทความนี้

http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

โปรแกรมเมอร์ IANA actionscript อย่างไรก็ตามความรู้สึกที่ฉันได้รับก็คือเพราะตัวเก็บขยะอาจไม่ทำงานเมื่อคุณต้องการ

ดังนั้น http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

ดังนั้นฉันขอแนะนำให้ลองใช้รหัสคอลเลกชันและดูว่าช่วยได้ไหม

private var gcCount:int;
private function startGCCycle():void{
    gcCount = 0;
    addEventListener(Event.ENTER_FRAME, doGC);
}
private function doGC(evt:Event):void{
    flash.system.System.gc();
    if(++gcCount > 1){
        removeEventListener(Event.ENTER_FRAME, doGC);
        setTimeout(lastGC, 40);
    }
}
private function lastGC():void{
    flash.system.System.gc();
}

16

น่าเสียดายที่เมื่อพูดถึงการจัดการหน่วยความจำในFlash / actionscriptคุณสามารถทำได้ไม่มากนัก ActionScript ได้รับการออกแบบมาให้ใช้งานง่าย (ดังนั้นจึงไม่ต้องการให้ผู้ใช้ต้องกังวลเกี่ยวกับการจัดการหน่วยความจำ)

ต่อไปนี้เป็นวิธีแก้ปัญหาแทนที่จะสร้างByteArrayตัวแปรให้ลองทำเช่นนี้

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

//Then when you are finished delete the variable from byteObject
delete byteObject.byteArray;

byteArrayคุณสมบัติไดนามิกของbyteObjectคุณอยู่ที่ไหนคุณสามารถเพิ่มหน่วยความจำที่จัดสรรให้กับมันได้


16

ฉันเชื่อว่าคุณตอบคำถามของตัวเองได้แล้ว

System.totalMemoryให้จำนวนหน่วยความจำทั้งหมดที่ "ใช้" ไม่ได้รับการจัดสรร เป็นที่ถูกต้องว่าแอปพลิเคชันของคุณอาจใช้เพียง 20 MB แต่มี 5 MB ที่ให้บริการฟรีสำหรับการจัดสรรในอนาคต

ฉันไม่แน่ใจว่าเอกสาร Adobe จะให้ความกระจ่างเกี่ยวกับวิธีการจัดการหน่วยความจำหรือไม่


11

ดังนั้นถ้าฉันโหลดพูด 20MB จาก MySQL ในตัวจัดการงาน RAM สำหรับแอปพลิเคชันจะเพิ่มขึ้นประมาณ 25MB จากนั้นเมื่อฉันปิดการเชื่อมต่อและพยายามกำจัด ByteArray แรมจะไม่ปล่อยให้ว่าง อย่างไรก็ตามหากฉันใช้ System.totalMemory โปรแกรมเล่นแฟลชจะแสดงว่าหน่วยความจำกำลังถูกปล่อยซึ่งไม่เป็นเช่นนั้น

โปรแกรมเล่นแฟลชทำบางอย่างเช่น Java และสงวนพื้นที่ฮีปไว้และไม่ปล่อยจนกว่าแอปจะหยุดทำงานหรือไม่

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


10

ดังนั้นถ้าฉันโหลดพูด 20MB จาก MySQL ในตัวจัดการงาน RAM สำหรับแอปพลิเคชันจะเพิ่มขึ้นประมาณ 25MB จากนั้นเมื่อฉันปิดการเชื่อมต่อและพยายามกำจัด ByteArray แรมจะไม่ปล่อยให้ว่าง อย่างไรก็ตามหากฉันใช้ System.totalMemory โปรแกรมเล่นแฟลชจะแสดงว่าหน่วยความจำกำลังถูกปล่อยซึ่งไม่เป็นเช่นนั้น

ผู้เล่นกำลัง "ปล่อย" หน่วยความจำ หากคุณย่อขนาดหน้าต่างและเรียกคืนคุณจะเห็นว่าตอนนี้ memeory อยู่ใกล้กับสิ่งที่ System.totalMemory แสดงมากขึ้น

คุณอาจสนใจใช้เครื่องมือสร้างโปรไฟล์ของ FlexBuilder ซึ่งสามารถแสดงให้คุณเห็นว่าคุณมีหน่วยความจำรั่วหรือไม่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.