Dỡ bỏ ByteArray bằng Actionscript 3


90

Làm cách nào để dỡ bỏ cưỡng bức một tệp ByteArraytừ bộ nhớ bằng ActionScript 3?

Tôi đã thử những cách sau:

// 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;
}

Câu trả lời:


34

Tôi không nghĩ bạn có điều gì phải lo lắng. Nếu System.totalMemoryđi xuống, bạn có thể thư giãn. Nó rất có thể là hệ điều hành không lấy lại bộ nhớ mới được giải phóng (dự đoán lần sau Flash Player sẽ yêu cầu thêm bộ nhớ).

Hãy thử làm điều gì đó khác rất tốn bộ nhớ và tôi chắc chắn rằng bạn sẽ nhận thấy rằng bộ nhớ được cấp cho Flash Player sẽ giảm và được sử dụng cho quá trình khác.

Như tôi đã hiểu, quản lý bộ nhớ trong hệ điều hành hiện đại không trực quan từ góc độ xem xét số lượng được phân bổ cho mỗi quá trình, hoặc thậm chí tổng số lượng được phân bổ.

Khi tôi sử dụng máy Mac trong 5 phút, 95% RAM 3 GB của tôi đã được sử dụng và nó sẽ giữ nguyên như vậy, không bao giờ bị hỏng. Đó chỉ là cách hệ điều hành xử lý bộ nhớ.

Miễn là nó không cần thiết ở nơi khác, ngay cả những tiến trình đã thoát vẫn được gán bộ nhớ cho chúng (ví dụ: điều này có thể khiến chúng khởi chạy nhanh hơn vào lần sau).


24

(Tôi không tích cực về điều này, nhưng ...)

AS3 sử dụng bộ sưu tập rác không xác định có nghĩa là bộ nhớ tham chiếu đến sẽ được giải phóng bất cứ khi nào bạn cảm thấy thích thời gian chạy (thường là không trừ khi có lý do để chạy, vì đó là một hoạt động tốn kém để thực thi). Đây là cách tiếp cận tương tự được sử dụng bởi hầu hết các ngôn ngữ thu gom rác hiện đại (như C # và Java).

Giả sử không có tham chiếu nào khác đến vùng nhớ được trỏ tới byteArrayhoặc các mục trong chính mảng, bộ nhớ sẽ được giải phóng tại một thời điểm nào đó sau khi bạn thoát khỏi phạm vi byteArrayđược khai báo.

Bạn có thể bắt buộc thu gom rác, mặc dù bạn thực sự không nên. Nếu bạn làm, hãy làm điều đó chỉ để thử nghiệm. Nếu bạn làm điều đó trong quá trình sản xuất, bạn sẽ ảnh hưởng đến hiệu suất nhiều hơn là giúp ích cho nó.

Để buộc GC, hãy thử (có, hai lần):

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

Bạn có thể đọc thêm ở đây .


19

Hãy xem bài viết này

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

Lập trình viên IANA actioncript, tuy nhiên cảm giác mà tôi nhận được là như vậy, bởi vì trình thu gom rác có thể không chạy khi bạn muốn.

Do đó http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

Vì vậy, tôi khuyên bạn nên thử mã bộ sưu tập của họ và xem nó có hữu ích không

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();
}

15

Thật không may khi nói đến quản lý bộ nhớ trong Flash / actioncript , bạn không thể làm được gì nhiều. ActionScript được thiết kế để dễ sử dụng (vì vậy họ không muốn mọi người phải lo lắng về việc quản lý bộ nhớ)

Sau đây là một cách giải quyết, thay vì tạo một ByteArraybiến, hãy thử cách này.

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

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

Trong trường hợp byteArraylà một tài sản năng động của byteObject, bạn có thể giải phóng bộ nhớ đã được phân bổ cho nó.


15

Tôi tin rằng bạn đã trả lời câu hỏi của riêng bạn.

System.totalMemorycung cấp cho bạn tổng dung lượng bộ nhớ được "sử dụng", không được cấp phát. Chính xác là ứng dụng của bạn có thể chỉ sử dụng 20 MB, nhưng nó có 5 MB miễn phí để phân bổ trong tương lai.

Tôi không chắc liệu các tài liệu của Adobe có làm sáng tỏ cách nó quản lý bộ nhớ hay không.


10

Vì vậy, nếu tôi tải 20MB từ MySQL, trong Task Manager, RAM cho ứng dụng sẽ tăng thêm khoảng 25MB. Sau đó, khi tôi đóng kết nối và cố gắng loại bỏ ByteArray, RAM không bao giờ giải phóng. Tuy nhiên, nếu tôi sử dụng System.totalMemory, trình phát flash hiển thị rằng bộ nhớ đang được giải phóng, điều này không đúng.

Có phải trình phát flash đang hoạt động giống như Java và dự trữ dung lượng heap và không giải phóng nó cho đến khi ứng dụng thoát?

Vâng và không, như bạn có thể đã đọc từ vô số bài đăng trên blog rằng GC trong AVM2 rất lạc quan và sẽ hoạt động theo những cách bí ẩn của riêng nó. Vì vậy, nó hoạt động hơi giống Java và cố gắng dành không gian heap. Tuy nhiên, nếu bạn để nó đủ lâu và bắt đầu thực hiện các thao tác khác đang tiêu tốn một số bộ nhớ đáng kể, nó sẽ giải phóng dung lượng trước đó. Bạn có thể thấy điều này bằng cách sử dụng hồ sơ qua đêm với một số thử nghiệm chạy trên ứng dụng của bạn.


9

Vì vậy, nếu tôi tải 20MB từ MySQL, trong Task Manager, RAM cho ứng dụng sẽ tăng thêm khoảng 25MB. Sau đó, khi tôi đóng kết nối và cố gắng loại bỏ ByteArray, RAM không bao giờ giải phóng. Tuy nhiên, nếu tôi sử dụng System.totalMemory, trình phát flash hiển thị rằng bộ nhớ đang được giải phóng, điều này không đúng.

Người chơi đang "giải phóng" bộ nhớ. Nếu bạn thu nhỏ cửa sổ và khôi phục nó, bạn sẽ thấy rằng memeory bây giờ gần hơn nhiều với những gì System.totalMemory hiển thị.

Bạn cũng có thể quan tâm đến việc sử dụng các công cụ lập hồ sơ của FlexBuilder, công cụ này có thể cho bạn biết nếu bạn thực sự bị rò rỉ bộ nhớ.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.