Ứng dụng của tôi cần nhiều bộ nhớ và cấu trúc dữ liệu lớn để thực hiện công việc của nó. Thường thì ứng dụng cần nhiều hơn 1 GB bộ nhớ, và trong một số trường hợp, khách hàng của tôi thực sự cần phải sử dụng phiên bản 64-bit của ứng dụng vì chúng có vài gigabyte bộ nhớ.Bắt buộc Windows tải DLL ở những nơi để bộ nhớ bị phân mảnh tối thiểu
Trong quá khứ, tôi có thể dễ dàng giải thích cho người dùng rằng nếu bộ nhớ đạt 1,6 đến 1,7 GB dung lượng bộ nhớ, nó đã hết bộ nhớ hoặc gần với tình trạng 'hết bộ nhớ' và họ cần để giảm bộ nhớ hoặc chuyển sang phiên bản 64 bit.
Năm cuối cùng tôi nhận thấy rằng ứng dụng thường chỉ sử dụng khoảng 1 GB trước khi hết bộ nhớ. Sau khi một số điều tra có vẻ như nguyên nhân của vấn đề này là phân mảnh bộ nhớ. Tôi đã sử dụng VMMAP (một tiện ích SysInternals) để xem xét việc sử dụng bộ nhớ của ứng dụng của tôi và thấy một cái gì đó như thế này:
Khu vực màu cam là bộ nhớ được cấp bởi ứng dụng của tôi. Các vùng màu tím là mã thực thi.
Như bạn có thể thấy ở nửa dưới của hình ảnh, các khu vực màu tím (là của DLL) được tải tại nhiều địa chỉ khác nhau, khiến bộ nhớ của tôi bị phân mảnh. Điều này không thực sự là vấn đề nếu khách hàng của tôi không có nhiều dữ liệu, nhưng nếu khách hàng của tôi có bộ dữ liệu chiếm hơn 1 GB và một phần của ứng dụng cần một khối bộ nhớ lớn (ví dụ: 50 MB), nó có thể dẫn đến lỗi phân bổ bộ nhớ, khiến ứng dụng của tôi bị lỗi.
Hầu hết cấu trúc dữ liệu của tôi dựa trên STL và thường không đòi hỏi nhiều bộ nhớ tiếp giáp, nhưng trong một số trường hợp (ví dụ: các chuỗi rất lớn), nó thực sự cần thiết để có một khối bộ nhớ liền kề. Thật không may, nó không phải là luôn luôn có thể thay đổi mã để nó không cần một khối bộ nhớ liền kề như vậy.
Các câu hỏi là:
- Làm thế nào tôi có thể ảnh hưởng đến vị trí nơi DLL được nạp trong bộ nhớ, mà không sử dụng một cách rõ ràng rebase trên tất cả các của DLL trên máy tính của khách hàng, hoặc không tải tất cả của DLL một cách rõ ràng.
- Có cách nào để chỉ định địa chỉ tải của tệp DLL trong tệp kê khai ứng dụng của riêng bạn không?
- Hoặc có cách nào để thông báo cho Windows (thông qua tệp kê khai không?) Để không phân tán tệp DLL xung quanh (tôi nghĩ rằng sự tán xạ này được gọi là ASLR).
Tất nhiên, giải pháp tốt nhất là giải pháp mà tôi có thể ảnh hưởng từ tệp kê khai của ứng dụng vì tôi dựa vào tải tự động/động của DLL của Windows.
Ứng dụng của tôi là ứng dụng hỗn hợp (được quản lý + không được quản lý), mặc dù phần chính của ứng dụng không được quản lý.
Bất kỳ đề xuất nào?
Đây có phải là thứ có thể giúp bạn không? http://msdn.microsoft.com/en-us/library/f7f5138s.aspx – detunized
mmm, bạn có thực sự cần nhiều bộ nhớ cùng một lúc không? Process Monitor lưu trữ nhật ký của nó trong bộ nhớ ảo và chỉ đưa dữ liệu vào không gian địa chỉ bộ nhớ của quá trình khi cần, kiểm tra http://blogs.msdn.com/b/oldnewthing/archive/2004/08/10/211890.aspx để biết mã Ví dụ –
Tôi không chắc mọi người để lại một câu trả lời hiểu được các nhánh của ASLR: http://en.wikipedia.org/wiki/ASLR –