2010-03-02 14 views
6

Tôi đã viết kịch bản tải cơ sở dữ liệu trong Coldfusion và tôi gặp sự cố khi tập lệnh từ từ hết bộ nhớ. Tôi đã chia từng tải bảng thành chủ đề riêng với <cfthread> và tôi đang gọi bộ thu gom rác khi bộ nhớ giảm xuống dưới 50% (đảm bảo có 30 giây giữa gc() cuộc gọi để ngăn bộ thu gom rác khỏi bộ nhớ hogging) .Tác động của bộ nhớ khi trả về truy vấn từ CFC

Tôi đã tạo CFC để giữ tất cả truy vấn cần thiết bởi tập lệnh. Kịch bản lệnh gọi hàm CFC thích hợp, sau đó trả về truy vấn, một số trong đó có kích thước lớn hơn 2 MB. Khi tôi nhìn vào Server Monitor trong khung nhìn chi tiết của trang Memory cho Active Threads, có vẻ như CFC của tôi đang giữ một bản sao của truy vấn trong bộ nhớ mặc dù tôi đã kiểm tra biến truy vấn và biến nằm ngoài phạm vi ở cuối của hàm. Ngoài ra, tôi có một bản sao của truy vấn trong bộ nhớ trong chủ đề của tôi. Vì vậy, tôi còn lại với những gì trông giống như hai bản sao của truy vấn trong bộ nhớ. Đây có thực sự là những gì đang xảy ra không? Nếu có, làm thế nào tôi có thể loại bỏ một bản sao của truy vấn khỏi bộ nhớ?

+0

anychance bạn có thể đăng mã gc() của bạn ở đâu đó? Tôi rất muốn thấy cách tiếp cận của bạn. – Antony

+0

Mã thu thập rác của tôi là http://www.fluentincode.com/2010/03/garbage-collection-in-coldfusion.html – stomcavage

Trả lời

11

Có rất nhiều các vấn đề tiềm năng ở đây, nhưng tôi sẽ cố gắng nhấn mạnh một số trong những điều quan trọng nhất để bạn có thể xem xét:

  1. Tại sao các chủ đề? Bạn có cần các chủ đề? Có một điểm nhất định mà tại đó bạn có thể tinkering quá nhiều cho lợi ích của riêng bạn.
  2. Thủ công buộc thu gom rác thải không nhất thiết phải là một ý tưởng hay. Điều chỉnh JVM để tự động thực hiện thu gom rác, nhưng đừng lạm dụng nó. Bộ sưu tập rác có xu hướng đắt tiền và có thể ảnh hưởng đến hiệu suất của ứng dụng nếu nó chạy quá thường xuyên.
  3. Bạn khởi tạo CFC bằng cách nào? Nếu bạn đang instantiating CFC trên mọi yêu cầu cho truy vấn, bạn sẽ gặp vấn đề về RAM theo thời gian, rò rỉ bộ nhớ chậm vì CFC được nạp vào RAM quá nhanh để thu gom rác để theo kịp. Đặt cược tốt nhất của bạn là để làm cho một singleton này. (nghĩa là, đặt nó vào phạm vi ứng dụng).
  4. Hãy lưu ý rằng việc biến đổi phạm vi biến không (theo như tôi hiểu) sẽ tự động giải phóng bộ nhớ ngay khi biến ngừng sử dụng. Bộ nhớ vẫn được dành riêng, mặc dù nó có khả năng bị gắn cờ bằng cách nào đó như là một phần của một thế hệ ngắn ngủi để nó (có thể?) Được làm sạch nhanh hơn. Nhưng điều này không đảm bảo bất cứ điều gì.
  5. Nếu bạn đang xem chủ đề đang hoạt động, có thể truy vấn sẽ không bị xóa cho đến khi kết thúc yêu cầu - không nhất thiết phải kết thúc cuộc gọi hàm. Có vẻ như thiếu kiên nhẫn đó sẽ thúc đẩy bạn mong đợi một truy vấn ngay lập tức chết ngay sau khi cuộc gọi chức năng được hoàn thành.
  6. ColdFusion queries are passed by reference, không theo giá trị. Bạn không thể nhận được 2 bản sao của truy vấn trong bộ nhớ, trừ khi bạn đang bằng cách nào đó bằng cách sử dụng duplicate() hoặc một hàm tương tự để sao chép một cách rõ ràng truy vấn.

Truy vấn có thể trả lại con trỏ cho truy vấn từ câu lệnh trả về của bạn. Truy vấn đó sẽ không được dọn sạch cho đến khi tất cả các quy trình được thực hiện tham chiếu nó. Vì vậy, nếu nó vượt qua các truy vấn đến một số quá trình khác, bạn sẽ không nhận được rằng truy vấn làm sạch ra khỏi bộ nhớ. Ví dụ: nếu bạn đặt truy vấn đó thành biến phiên, con trỏ đó sẽ không đi đâu cho đến khi biến phiên đó biến mất, bất kể bạn cố gắng thu gom rác thải thường xuyên như thế nào.

Chỉ một vài điều cần xem xét.

+1

Câu trả lời tuyệt vời. Tôi không mong muốn giải thích tất cả những điều đó, nhưng có vẻ như tôi không phải làm vậy. :-) –

+0

Xin cảm ơn! :) –

+0

Cảm ơn. Bạn nên biết rằng các truy vấn được chuyển qua tham chiếu. Tôi không thể tìm thấy thông tin đó trong tìm kiếm trực tuyến của mình. Tôi đang khởi tạo CFC một lần cho mỗi chuỗi. Tôi đang thực hiện nhiều chủ đề vì bộ nhớ dường như không được dọn dẹp hoàn toàn, ngay cả với gc(), cho đến khi yêu cầu hoàn tất. Dường như một luồng là yêu cầu riêng của nó, vì vậy tôi đa luồng nó để dọn dẹp. Tôi đã đặt biến truy vấn thành chuỗi trống khi tôi sử dụng xong và điều đó dường như làm giảm một số vấn đề về bộ nhớ. – stomcavage

0

Tôi đã gặp sự cố tương tự với việc xử lý chèn dữ liệu lớn, trong đó mỗi hàng yêu cầu xử lý mở rộng liên quan đến nhiều CFC. Có vẻ như các tham chiếu JDBC ResultSet, Statement và Connection được tạo bởi <cfquery> được giữ cho đến khi kết thúc yêu cầu.Điều này có nghĩa là việc vô hiệu biến truy vấn của bạn không ảnh hưởng đến việc sử dụng bộ nhớ. Cách tôi nhận được xung quanh điều này là để thực hiện một cuộc gọi gateway đến một hàm CFC để xử lý 100 hàng, sau đó hàm đó thực hiện một cuộc gọi gateway khác cho 100 hàng tiếp theo, vv cho đến khi tất cả các hàng được xử lý. Bởi vì mỗi cuộc gọi cổng riêng lẻ thực sự thoát, nó giải phóng tất cả các xử lý của nó và bộ nhớ đó được phục hồi.

+0

Rất thú vị. Tôi có thể thử. Cảm ơn. – stomcavage

Các vấn đề liên quan