2013-08-04 44 views
7

Tôi đã sử dụng nhiều lần nhưng tôi chưa bao giờ đọc nhiều về cách chúng thực sự hoạt động. Tôi cũng không biết nhiều về họ ngoài luồng đó chỉ là một phép ẩn dụ. Một luồng chỉ biểu diễn một chuỗi các byte. Tôi không biết nhiều về cách chúng thực sự hoạt động, tôi đoán việc mở một luồng tệp trong Java tương tác với hệ điều hành có chức năng cung cấp "con trỏ" cho luồng.Các luồng trong Java ảnh hưởng đến mức tiêu thụ bộ nhớ như thế nào?

Về cơ bản, câu hỏi của tôi là cách luồng ảnh hưởng đến mức tiêu thụ bộ nhớ. Khi bạn có ví dụ một dòng đầu vào và bạn bắt đầu đọc từ nó, bạn chỉ bắt đầu tăng mức tiêu thụ bộ nhớ với số lượng byte được đọc? Khi mở một dòng trong Java bạn không thực sự tải toàn bộ tập tin trước khi bạn bắt đầu đọc? Nếu bạn đọc từ một luồng và ghi trực tiếp vào luồng khác, bạn chỉ tăng bộ nhớ với số byte mà bạn đã đọc (và có khả năng có trong bộ đệm)? Nếu bạn đọc byte vào một mảng byte trong java thì bạn tăng mức tiêu thụ bộ nhớ với kích thước của tệp?

Có thể âm thanh như một câu hỏi kỳ lạ nhưng tôi có thể cần một số hướng dẫn/chỉnh sửa về sự hiểu biết của mình. Cảm ơn.

+0

Bạn có một lời giải thích rất hay [ở đây] (http://www.ibm.com/developerworks/library/j-zerocopy/index.html) không sao chép. Ngoài ra nó giải thích các bộ đệm và sử dụng bộ nhớ. –

Trả lời

3

Có gần như không có phí trên bộ nhớ sau khi bạn bắt đầu đọc từ InputStream. Có rất ít hệ điều hành trên không để mở một tệp và một chi phí nhỏ trong JVM để phân bổ đối tượng mới. Cũng có thể có một chi phí nhỏ trong trường hợp bạn sử dụng BufferedInputStream theo mặc định là 8KB.

Chi phí cho việc viết rất nhiều phụ thuộc vào nơi bạn viết thư. Nếu đó là FileOutputStream, thì nó giống như được mô tả ở trên. Nếu đó là ByteArrayOutputStream, thì đó là byte (2 * chiều dài luồng) trong trường hợp tốt nhất và (3 * chiều dài luồng) byte trong trường hợp xấu nhất. I E. để sao chép 10k byte từ một InputStream thành một mảng byte 30k byte sẽ được cấp phát trong trường hợp xấu nhất.

Lý do cho điều này là ByteArrayOutputStream tăng trưởng kích thước 2 lần sau khi đạt đến giới hạn và nó cũng cấp phát bộ đệm mới khi bạn gọi toByteArray().

5

Tất cả câu trả lời ở trên đều là câu trả lời tuyệt vời nhưng tôi không tin họ trả lời câu hỏi ban đầu của bạn về mức tiêu thụ bộ nhớ.

Trong Java, bạn có thể xem các luồng theo nhiều cách. Trước tiên, bạn có các luồng thô là luồng mức thấp nhất và tương tác với hệ điều hành cơ bản (Tệp, Mạng, v.v.) với chi phí bộ nhớ tối thiểu. Thứ hai là các luồng đệm có thể được sử dụng để bọc luồng thô và thêm một số bộ đệm và cải thiện đáng kể hiệu suất. Tính năng lưu vào luồng bổ sung thêm một lượng bộ nhớ cố định cho bộ đệm và có thể được thiết lập bởi ứng dụng của bạn. Bạn không chắc chắn những gì mặc định là nhưng nó có lẽ là một cái gì đó tối thiểu như 32K.

Loại thứ ba của luồng là một luồng bộ nhớ (tức là ByteArrayInput/Ouput) sử dụng nhiều bộ nhớ như bạn viết cho chúng và sẽ phát triển khi cần và không thải bỏ bộ nhớ của chúng cho đến khi số tham chiếu chuyển sang không (chúng là Không còn được sử dụng). Những dòng này rất hữu ích nhưng rõ ràng có thể tiêu thụ rất nhiều bộ nhớ.

Loại cuối cùng thực sự không phải là luồng mà là một lớp I/O được gọi là Trình đọc cung cấp hỗ trợ chuyển đổi dữ liệu đến và từ luồng như được chỉ ra ở trên. Các luồng này hoạt động trên nguyên bản. bộ đệm hoặc luồng bộ nhớ và sẽ tiêu thụ nhiều bộ nhớ như luồng cơ bản đang được sử dụng.

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