2009-02-26 33 views
6

Tôi mới có nhu cầu phân bổ bộ nhớ lớn với bộ nhớ mới.Phân bổ các khối bộ nhớ lớn với

Tôi đang mắc kẹt với việc sử dụng mới vì tôi đang viết một mô hình cho phía nhà sản xuất của một ứng dụng hai phần. Mã sản xuất thực tế đang phân bổ các khối lớn này và mã của tôi có trách nhiệm xóa chúng (sau khi xử lý chúng).

Có cách nào tôi có thể đảm bảo ứng dụng của mình có khả năng phân bổ một lượng bộ nhớ lớn như vậy từ heap không? Tôi có thể đặt heap thành kích thước lớn hơn không?

Trường hợp của tôi là 64 khối 288000 byte. Đôi khi tôi nhận được 12 để phân bổ và thời gian khác tôi nhận được 27 để phân bổ. Tôi nhận được một std :: bad_alloc ngoại lệ.

Đây là: C++, GCC trên Linux (32bit).

+0

Bạn có cần tất cả điều đó trong một lần không? Nếu không, bạn có thể sử dụng một bộ nhớ-pool và một phân bổ tùy chỉnh để quản lý hồ bơi. – dirkgently

+0

Như tôi đã nói, tôi đang cố gắng giả định mã sản xuất sẽ làm gì. Tôi sẽ sử dụng một hồ bơi bộ nhớ phân bổ tĩnh nếu tôi có thể. – JeffV

+0

Bạn có thể sử dụng một hồ bơi được phân bổ tĩnh và thay thế các cuộc gọi của bạn để xóa bằng chức năng 'FreeBlock'. Bằng cách này bạn có thể kiểm tra xem bạn đã điền vào tất cả các khối có được. –

Trả lời

9

Đối với những mới trong C++/GCC/Linux (32bit) ...

Nó được một lúc, và nó thực hiện phụ thuộc, nhưng tôi tin rằng mới sẽ, đằng sau hậu trường, gọi malloc(). Malloc(), trừ khi bạn yêu cầu điều gì đó vượt quá không gian địa chỉ của quy trình hoặc bên ngoài giới hạn được chỉ định (ulimit/getrusage), sẽ không thành công. Ngay cả khi hệ thống của bạn không có đủ RAM + SWAP. Ví dụ: malloc (1gig) trên một hệ thống với 256Meg RAM + 0 SWAP sẽ, tôi tin rằng, thành công.

Tuy nhiên, khi bạn sử dụng bộ nhớ đó, hạt nhân cung cấp các trang thông qua cơ chế cấp phát lười biếng. Tại thời điểm đó, khi bạn lần đầu tiên đọc hoặc ghi vào bộ nhớ đó, nếu hạt nhân không thể cấp phát các trang bộ nhớ cho quá trình của bạn, nó sẽ giết chết quá trình của bạn.

Đây có thể là sự cố trên máy tính dùng chung, khi đồng nghiệp của bạn bị rò rỉ lõi chậm. Đặc biệt là khi ông bắt đầu gõ ra các quy trình hệ thống.

Vì vậy, thực tế là bạn đang thấy std :: bad_alloc ngoại lệ là "thú vị".

Bây giờ new sẽ chạy hàm tạo trên bộ nhớ được cấp phát, chạm vào tất cả các trang bộ nhớ đó trước khi trả về. Tùy thuộc vào việc triển khai, nó có thể đang bẫy tín hiệu ngoài bộ nhớ.

Bạn đã thử điều này với đồng bằng o'l malloc?

Bạn đã thử chạy chương trình "miễn phí" chưa? Bạn có đủ bộ nhớ không?

Như những người khác đã đề xuất, bạn đã kiểm tra giới hạn/ulimit/getrusage() cho khó khăn & ràng buộc mềm?

Mã của bạn trông như thế nào, chính xác? Tôi đang đoán ClassFoo mới [N]. Hoặc có lẽ char mới [N].

Kích thước là gì (ClassFoo)? N là gì?

Phân bổ 64 * 288000 (17.58Meg) không đáng kể đối với hầu hết các máy hiện đại ... Bạn có đang chạy trên một hệ thống nhúng hay thứ gì đó đặc biệt khác không?

Ngoài ra, bạn có đang liên kết với một đơn vị phân bổ mới tùy chỉnh mới không? Lớp học của bạn có đơn vị phân bổ mới mới không?

Cấu trúc dữ liệu (lớp) của bạn có phân bổ các đối tượng khác như một phần của hàm tạo của nó không?

Có ai đó đã giả mạo thư viện của bạn không? Bạn đã cài đặt nhiều trình biên dịch chưa? Bạn đang sử dụng sai đường dẫn bao gồm hoặc thư viện?

Bạn có đang liên kết với các tệp đối tượng cũ không? Bạn có cần phải biên dịch lại tất cả các tệp nguồn của mình không?

Bạn có thể tạo chương trình thử nghiệm tầm thường không? Chỉ là một vài dòng mã tái tạo lỗi? Hoặc là vấn đề của bạn ở nơi khác, và chỉ hiển thị ở đây?

-

Đối với những gì nó có giá trị, tôi đã được phân bổ trên các khối dữ liệu 2Gig với mới trong 32bit linux dưới g ++. Vấn đề của bạn nằm ở nơi khác.

+1

+1 cho sự cố kỹ lưỡng! – JeffV

4

Có thể bạn đang bị giới hạn bởi quy trình 'ulimit; chạy ulimit -a và kiểm tra giới hạn kích thước bộ nhớ và dữ liệu virutal. Ngoài ra, bạn có thể đăng mã phân bổ của mình để chúng tôi có thể xem những gì đang diễn ra không?

+0

Tôi đã kiểm tra bằng cách sử dụng getrlimit (RLIMIT_AS, & lim), nó đang báo cáo 4GB ở mức hiện tại và tối đa. – JeffV

+0

@ Jeff: Bạn chỉ đang cố gắng phân bổ khoảng 18Mb! Đó là một pittance trên bất kỳ máy tính hiện đại. Có * phải * là một cái gì đó khác phân bổ tấn bộ nhớ bên trong chương trình của bạn. –

0

tôi sẽ đề xuất phân bổ tất cả bộ nhớ của bạn khi khởi động chương trình và sử dụng vị trí mới để định vị bộ đệm của bạn. tại sao cách tiếp cận này? tốt, bạn có thể tự theo dõi phân mảnh và như vậy. không có cách nào để xác định dung lượng bộ nhớ có thể được phân bổ cho quá trình của bạn. Tôi đang tích cực có một cuộc gọi hệ thống cụ thể linux sẽ giúp bạn có được thông tin đó (không thể nghĩ về nó là gì). chúc may mắn.

0

Thực tế là bạn đang nhận được hành vi khác nhau khi bạn chạy chương trình tại các thời điểm khác nhau làm cho tôi nghĩ rằng mã phân bổ không phải là vấn đề thực sự. Thay vào đó, ai đó đang sử dụng bộ nhớ và bạn là người canary phát hiện ra nó bị mất tích.

Nếu "ai đó khác" trong chương trình của bạn, bạn sẽ có thể tìm thấy nó bằng cách sử dụng Valgrind.

Nếu ai đó khác là một chương trình khác, bạn sẽ có thể xác định được điều đó bằng cách truy cập runlevel khác (mặc dù bạn không nhất thiết phải biết thủ phạm).

1

Cập nhật:

Tôi đã khắc phục lỗi lập chỉ mục mảng và phân bổ chính xác ngay bây giờ.

Nếu tôi phải đoán ... Tôi đã đi bộ trên toàn bộ đống của mình và đang rối tung với cấu trúc dữ liệu của malloc. (??)

+0

Điều đó chắc chắn sẽ làm được! Đôi khi tôi sử dụng các phương thức truy cập INLINED với các câu lệnh khẳng định để nhận các vấn đề như vậy trong giai đoạn gỡ lỗi. (Chúng được biên dịch cho mã sản xuất.) –

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