Khi nào và tại sao một lớp Pool cần thiết để giữ các đối tượng?


12

Tôi đã nghiên cứu opengl es và một ví dụ tôi thấy là sử dụng lớp "Pool" để theo dõi các sự kiện bàn phím và cảm ứng.

Ai đó có thể vui lòng giải thích làm thế nào và tại sao một lớp pool là cần thiết. Từ những gì tôi đã đọc, nó có liên quan đến việc thu gom rác và giới hạn số lượng các lớp đầu vào được tạo ra.

Tất cả điều này có vẻ hơi trừu tượng đối với tôi, vì vậy nếu ai đó có thể vui lòng giải thích những gì đang xảy ra, tôi sẽ đánh giá cao nó, tôi sẽ dán một số mã ở đây:

    public Pool(PoolObjectFactory <> factory, int maxSize) {            
        this.factory = factory;         
        this.maxSize = maxSize;         
        this.freeObjects = new ArrayList < T > (maxSize);     
    }  
         
    public T newObject() {        
        T object = null ;        
        if (freeObjects.isEmpty())            
            object = factory.createObject();        
        else             
            object = freeObjects.remove(freeObjects.size() - 1);        
            return object;     
    } 

    public void free(T object) {         
        if (freeObjects.size() < maxSize)             
            freeObjects.add(object);     
    }

    PoolObjectFactory <TouchEvent> factory = new PoolObjectFactory <TouchEvent> () {
     
    @Override     
    public TouchEvent createObject() {         
         return new TouchEvent();     
    } 

    Pool <TouchEvent> touchEventPool = new Pool <TouchEvent> (factory, 50); 
    TouchEvent touchEvent = touchEventPool.newObject(); 
    . . . do something here . . . 
    touchEventPool.free(touchEvent);

Cảm ơn!

Câu trả lời:


17

Các hồ bơi được sử dụng khi số lượng đối tượng sẽ dao động mạnh và được sử dụng để giảm lượng phân bổ bộ nhớ và thu gom rác.

Sử dụng một nhóm đối tượng mới () phân bổ bộ nhớ mới được thay thế bằng cách kéo một đối tượng đã được phân bổ từ nhóm. Điều này nhanh hơn nhiều ngay cả khi bạn đi và đặt lại mọi biến trong đối tượng cũ về mặc định.

Nếu bạn tạo một mục mới mỗi lần bạn có số lượng lớn trên đầu vì bộ nhớ phải được phân bổ cho từng đối tượng. Ngoài ra bởi vì bạn đang tạo ra rất nhiều đối tượng, bạn phải dọn dẹp chúng thường xuyên, điều này khiến cho trình thu gom rác được chạy rất thường xuyên làm tổn hại đến hiệu suất.

Một ví dụ phổ biến là đạn.

Đối với FPS có thể có 0 viên đạn trên màn hình sau đó 1000 giây tiếp theo và sau đó 0 lần nữa sau đó. Nếu bạn tạo một viên đạn mới cho mỗi một phát, việc cấp phát bộ nhớ không đổi sẽ cực kỳ hiệu quả. Ngoài ra, trình thu gom rác phải theo dõi tất cả các trường hợp này và dọn dẹp định kỳ, việc này thậm chí còn mất nhiều thời gian hơn.

Nếu bạn có một nhóm 5000 viên đạn và chỉ cập nhật và tương tác với những viên đạn không có trong danh sách freeObjects, bạn chỉ có 5000 phân bổ cho dù cuộc chiến kéo dài bao lâu thay vì 1 lần phân bổ cho mỗi viên đạn. Ngoài ra, người thu gom rác chỉ cần chạy khi mọi khả năng xảy ra hỏa hoạn đã kết thúc. Tương tác với bộ nhớ rất chậm, do đó, điều này tạo ra một tác động lớn đến hiệu suất và đảm bảo khối lượng công việc được phân bổ đều, ngăn chặn tốc độ khung hình.


Vì vậy, tôi nghĩ rằng một lớp pool cho các hiệu ứng hạt sẽ vô cùng cần thiết, phải không?
mathacka

Vâng, chính xác là loại hồ tình huống được thiết kế cho.
ClassicThunder

Có phải thực hành tốt hơn để có một nhóm lớp, đó là các đối tượng của riêng mình hoặc sử dụng một nhà máy? Tức là Object.getObject () so với ObjectFactory.getObject ()
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.