2011-01-14 32 views
5

Tôi dường như có một số rò rỉ bộ nhớ khá lớn trong ứng dụng mà tôi đang làm việc. Bản thân ứng dụng không phải là rất phức tạp. Cứ sau 15 giây, trang yêu cầu xấp xỉ 40kb JSON từ máy chủ và vẽ một bảng trên trang bằng cách sử dụng nó. Sẽ rẻ hơn khi vẽ bảng vì dữ liệu thường luôn mới. Tôi đính kèm một vài sự kiện vào bảng, khoảng 5 mỗi dòng, 30 dòng trong bảng. Tôi đã sử dụng phương thức .html() của jQuery để đưa html mới vào thùng chứa và ghi đè lên hiện tại. Tôi làm điều này đặc biệt để các chức năng dọn dẹp đặc biệt của jQuery đi vào và cố gắng tách tất cả các sự kiện trên các phần tử trong phần tử mà nó ghi đè lên. Sau đó tôi cũng xóa các biến lớn của html khi chúng được gửi đến DOM bằng cách sử dụng delete my_var.Ứng dụng JS nặng của Ajax sử dụng quá nhiều bộ nhớ theo thời gian

Tôi đã kiểm tra các tham chiếu vòng tròn và các sự kiện được đính kèm không bao giờ bị xóa một vài lần, nhưng không bao giờ thực sự khai thác nó. Tôi đã tự hỏi nếu ai đó có thể cho tôi một vài gợi ý về cách tối ưu hóa một ứng dụng rất nặng như thế này. Tôi chỉ chọn "Hiệu suất cao Javascript" của Nicholas Zakas, nhưng không có nhiều thời gian để tham gia vào nó.

Để đưa ra ý tưởng về dung lượng bộ nhớ này đang sử dụng, sau 4 ~ giờ, nó đang sử dụng khoảng 420.000k trên chrome và nhiều hơn nữa trên Firefox hoặc IE.

Cảm ơn!

+3

Để nhận được câu trả lời hữu ích, có thể bạn sẽ cần cung cấp mẫu mã để tái tạo sự cố. –

+0

Sẽ phải xem mã để hữu ích hơn. Nếu nó xảy ra trong FF * thì có khả năng là do các tài nguyên không được phát hành hoặc ngữ cảnh thực thi *. Các phiên bản cũ hơn của IE là (nhiều hơn) dễ bị "không phù hợp với đối tượng suốt đời" giữa DOM và JS engine. Hãy nhớ rằng, ngay cả khi bạn đặt lại dữ liệu trong ngữ cảnh thực thi, bạn vẫn chưa giết ngữ cảnh thực thi! (Nó thực sự là một lỗi nếu trình duyệt không phát hành các sự kiện của các phần tử bị loại bỏ khỏi DOM.) Lỗi này nghe có vẻ thú vị, vui lòng cập nhật với (tối thiểu) test-case :-) –

+0

Tôi sẽ cố gắng xây dựng một JS đơn giản tệp hiển thị cùng các triệu chứng. –

Trả lời

1

tôi muốn đề nghị viết một phiên bản thử nghiệm của kịch bản của bạn mà không cần sự kiện. Các tham chiếu vòng tròn DOM/JS có thể rất khó phát hiện. Bằng cách loại bỏ một số biến từ phương trình, bạn có thể thu hẹp tìm kiếm của mình một chút.

+0

Sự cố đã kết thúc là tôi đã đính kèm các biểu đồ google vào mỗi hàng trong hộp thoại bật lên ẩn. Một khi tôi gỡ bỏ điều đó, việc sử dụng bộ nhớ đã giảm xuống. Bằng cách viết một phiên bản thử nghiệm, tôi thấy điều này. Cảm ơn. –

0

Tôi đã gặp sự cố tương tự chỉ trong tuần này. Hóa ra tôi có một tham chiếu vòng tròn trong cơ sở dữ liệu của mình. Tôi đã có một mục hàng tồn kho ABC123 được gắn cờ là được thay thế bằng XYZ321 và tôi cũng đã có XYZ321 được gắn cờ là đang được thay thế bởi ABC123. Đôi khi tham chiếu vòng tròn không có trong mã PHP.

+0

Khi tôi nói tham chiếu vòng tròn, tôi đang nói về khi một phần tử đề cập đến một đối tượng, trong đó đề cập đến cùng một yếu tố. Hãy xem bài viết này: http://www.ibm.com/developerworks/web/library/wa-memleak/ –

1

Tôi đã trải nghiệm điều tương tự. Tôi đã có một đoạn mã được kiểm tra 10 giây một lần và lấy ra một số lỗi của người dùng hiện tại (nhập/kiểm tra dữ liệu), một số nguyên đơn giản. Điều này sau đó được sử dụng để thay thế văn bản bên trong một div (để người dùng biết khi nào các lỗi mới được tìm thấy trong công việc của họ). Nếu bỏ qua đêm, trình duyệt sẽ kết thúc bằng cách sử dụng hơn 1gb bộ nhớ!

Gần nhất tôi đến để giải quyết vấn đề là giảm việc bỏ phiếu xảy ra cứ sau 2 phút thay vào đó và yêu cầu người dùng đóng cửa vào cuối ngày. Một giải pháp tốt hơn vẫn là sử dụng Ajax Push Engine để đẩy dữ liệu vào trang CHỈ khi một lỗi được tạo ra. Điều này sẽ dẫn đến dữ liệu được gửi ít thường xuyên hơn và do đó ít bộ nhớ hơn được sử dụng.

+0

Đáng buồn thay, chúng tôi có cập nhật 10-15 giây một lần, trên tất cả dữ liệu. Ngoài ra, vì đây là "sản phẩm", chúng tôi không thể yêu cầu mọi người khởi động lại trình duyệt của họ :) Cảm ơn bạn đã có các mẹo. –

1

Bạn có đang lưu bất kỳ thứ gì vào abject/array không? Tôi đã có điều này xảy ra trước đây với một plugin chrome, nơi một mảng chỉ tiếp tục nhận được lớn hơn và lớn hơn. Điều này nghe có vẻ như nó có thể là vấn đề của bạn, đặc biệt là xem xét bạn đang tìm nạp 40k.

+0

Yêu cầu trả về một đối tượng json lớn, nhưng nó ghi đè lên đối tượng trước đó trong cùng một biến. Điều đó sẽ ghi đè cùng một khối nội dung cũ với nội dung mới. –

1

Đoạn trích sẽ tuyệt vời như thể bạn đang tạo biến mới mỗi lần và các biến cũ không bị loại ra khỏi phạm vi do đó không bị thu gom rác.

Đồng thời thử và đóng gói thêm JS của bạn bằng cách sử dụng các hàm tạo và các đối tượng của các đối tượng ect. Khi JS chỉ là một danh sách các hàm và tất cả các biến có phạm vi toàn cục thay vì là các thuộc tính của một cá thể, JS của bạn có thể chiếm nhiều bộ nhớ.

1

Tại sao không vẽ bảng và chỉ đính kèm các sự kiện một lần và chỉ thay thế dữ liệu bảng sau mỗi 15 giây?

1

1) Jquery Ajax wrapper, được gọi là định kỳ, dẫn đến rò rỉ bộ nhớ và cộng đồng là nhận thức được rằng (mặc dù các vấn đề trên wrapper ajax không phải là bằng cách xa như xấu xí như trường hợp của bạn).

2) Khi nói đến tối ưu hóa, bạn đã thực hiện bước đầu tiên (sử dụng các cuộc gọi json nhẹ) và phương pháp xóa, nhưng vấn đề nằm trong vùng "đính kèm sự kiện" và phương thức html.

Ý của tôi là: 1) có thể bạn đang gắn lại trình nghe sau mỗi lần gọi html() 2) bạn vẽ lại bảng lỗ trên mỗi cuộc gọi ajax. Điều này thực sự dẫn đến rò rỉ bộ nhớ.

Bạn cần phải: 1) vẽ bảng (với nội dung lần đầu tiên) ở phía máy chủ 2) $ (document) .ready bạn đính kèm nghe đến các tế bào của bảng 3) dịch vụ cuộc gọi json với ajax, phân tích phản ứng 4) nạp bảng với dữ liệu mảng phân tích cú pháp

Hãy cho chúng tôi những gì bạn đã achived trong khi đó :)

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