2012-01-29 37 views
6

Chúng tôi có Dịch vụ Windows được tạo trong .Net 4.0, dịch vụ phân tích các tệp văn bản lớn được tạo thành từ các dòng giá trị được phân cách bằng dấu phẩy (Một vài triệu dòng, 10 giá trị), không có vấn đề ở đây, chúng ta có thể đọc các dòng, chia chúng thành một bộ sưu tập Key/Value và xử lý các giá trị. Để xác thực các giá trị chúng tôi đang sử dụng Paralellism dữ liệu để chuyển các giá trị, về cơ bản là một mảng giá trị trong các định dạng cụ thể, đến phương thức thực hiện xác thực RegEx trên các giá trị riêng lẻ. Cho đến bây giờ, chúng tôi đã sử dụng các biểu thức chính quy tĩnh, không phải phương thức RegEx.IsMatch tĩnh nhưng thuộc tính RegEx tĩnh với RegexOption được định nghĩa là RegexOptions.Compiled, như được mô tả chi tiết bên dưới.Sử dụng bộ nhớ và các vấn đề đã biết với RegEx và các phiên bản Framework khác nhau

private static Regex clientIdentityRegEx = new Regex("^[0-9]{4,9}$", RegexOptions.Compiled); 

Sử dụng phương pháp này, chúng tôi đã có một bộ nhớ khá chuẩn, bộ nhớ tăng nhẹ với số lượng lớn hơn các giá trị trong mỗi dòng, thời gian thực hiện là nhiều hay ít tuyến tính vào tổng số dòng.

Để cho phép biểu thức chính quy được sử dụng trong các dự án khác, thay đổi phiên bản khung, gần đây chúng tôi đã di chuyển thuộc tính RegEx tĩnh sang dự án tiện ích chung hiện được biên dịch bằng .Net 2.0 CLR (Biểu thức chính quy thực tế không thay đổi), số lượng các thuộc tính RegEx tiếp xúc đã tăng lên khoảng 60, từ 25 trở lên. Kể từ khi làm điều này, chúng tôi đã bắt đầu chạy vào các vấn đề bộ nhớ, tăng bộ nhớ 3 hoặc nhiều lần so với dự án ban đầu. Khi chúng tôi cấu hình dịch vụ đang chạy, chúng ta có thể thấy bộ nhớ dường như bị "rò rỉ" từ RegEx.IsMatch, không phải bất kỳ RegEx cụ thể nào nhưng khác nhau tùy thuộc vào đó được gọi.

Tôi đã tìm thấy nhận xét sau về số MSDN blog post cũ từ một trong các nhóm BCL liên quan đến .Net 1.0/1.1 RegEx.

Thậm chí còn có nhiều chi phí hơn cho việc biên soạn cần đề cập. Phát ra IL với Reflection.Emit tải rất nhiều mã và sử dụng rất nhiều bộ nhớ, và đó không phải là bộ nhớ mà bạn sẽ quay trở lại. Ngoài ra. trong v1.0 và v1.1, chúng tôi không bao giờ có thể giải phóng IL mà chúng tôi đã tạo ra, có nghĩa là bạn đã bị rò rỉ bộ nhớ bằng cách sử dụng chế độ này. Chúng tôi đã khắc phục vấn đề đó trong Whidbey. Nhưng dòng dưới cùng là bạn chỉ nên sử dụng chế độ này cho một tập hợp hữu hạn các biểu thức mà bạn biết sẽ được sử dụng nhiều lần.

Tôi sẽ thêm chúng tôi đã lược tả "hầu hết" các cuộc gọi RegEx phổ biến và không thể sao chép riêng vấn đề.

Đây có phải là sự cố đã biết với CLR .Net 2.0 không?

Trong bài báo là nhà văn tiểu bang "Nhưng điểm mấu chốt là bạn chỉ nên sử dụng chế độ này cho một tập hữu hạn các biểu thức mà bạn biết sẽ được sử dụng lặp đi lặp lại", những gì có thể là hữu hạn số biểu thức được sử dụng theo cách này và điều này có thể là nguyên nhân không?

Cập nhật: Phù hợp với câu trả lời từ @Henk Holterman có bất kỳ thực hành tốt nhất cho benchmark thử nghiệm Regular Expressions, cụ thể RegEx.IsMatch, khác hơn là sử dụng sức mạnh vũ phu tuyệt đối bằng định dạng khối lượng và thông số?

Trả lời: Câu trả lời giả của "Các trường hợp yêu cầu số lượng giới hạn, số lượng cố định của đối tượng RegEx" là khá nhiều điểm, chúng tôi đã thêm các RegEx'es tĩnh vào lớp cho đến khi chúng tôi tách biệt các biểu thức với mức tăng đáng chú ý trong việc sử dụng bộ nhớ, chúng được di chuyển đến các lớp tĩnh riêng biệt mà dường như đã giải quyết được một số vấn đề về bộ nhớ.

Nó xuất hiện, mặc dù tôi không thể xác nhận điều này, có sự khác biệt giữa việc sử dụng RegEx được biên dịch giữa .Net 2.0 CLR và .Net 4.0 CLR do vấn đề bộ nhớ không xảy ra khi tuân thủ duy nhất cho khuôn khổ .Net 4.0 . (Bất kỳ xác nhận nào?)

+1

OK, bạn đã khôi phục mã của mình _and_ tăng lên đáng kể nr của RegEx. Bạn có thể quay trở lại và làm một lúc? –

+0

Trình lược tả chính xác cho bạn biết điều gì? Về loại bộ nhớ bị rò rỉ? –

+0

Có, chúng tôi đã thực hiện điều này vào cuối ngày hôm nay và với dự án được biên dịch thành .Net 2.0 CLR đã nhận được sự gia tăng bộ nhớ với cùng số lượng RegEx đã sử dụng trước đó, dường như không có mối quan hệ trực tiếp với số lượng chúng ta thêm vào. được gọi và loại biểu thức. – Lloyd

Trả lời

1

Kịch bản yêu cầu số lượng đối tượng RegEx có giới hạn, cố định. Điều đó không nên bị rò rỉ. Bạn nên xác minh rằng trong tình huống mới, các đối tượng RegEx vẫn đang được sử dụng lại.

Khả năng khác là số tăng (60 từ 25) biểu thức. Chỉ một trong số họ có thể phức tạp hơn một chút, dẫn đến quá tải ngược?

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