2011-07-04 26 views
6

Sau đây là một chiết xuất từ ​​MSDN:CLR/JVM có giữ một hồ bơi đơn cho tất cả các ứng dụng .net/java đang chạy không?

Bộ thực thi ngôn ngữ chung bảo tồn chuỗi lưu trữ bằng cách duy trì một bảng, gọi là hồ sinh nội trú, có chứa một tham chiếu duy nhất để mỗi chuỗi chữ độc đáo tuyên bố hoặc tạo lập trình trong chương trình của bạn. Do đó, một thể hiện của một chuỗi theo nghĩa đen với một giá trị cụ thể chỉ tồn tại một lần trong hệ thống.

Ví dụ, nếu bạn gán cùng chuỗi chữ cho một số các biến, thời gian chạy lấy cùng tham chiếu đến chuỗi chữ từ hồ bơi tập và gán nó vào mỗi biến .

Phương thức Intern sử dụng hồ bơi thực tập để tìm kiếm chuỗi bằng giá trị của str. Nếu chuỗi đó tồn tại, tham chiếu của nó trong hồ bơi thực tập là được trả lại. Nếu chuỗi không tồn tại , tham chiếu đến str được thêm vào hồ bơi thực, sau đó tham chiếu được trả về. .... Nếu bạn đang cố gắng để giảm tổng số bộ nhớ mà ứng dụng của bạn phân bổ , hãy ghi nhớ rằng việc thực hiện chuỗi có hai hiệu ứng phụ không mong muốn là . Đầu tiên, bộ nhớ được phân bổ cho các chuỗi tập trung không được phát hành cho đến khi thời gian chạy ngôn ngữ chung (CLR) chấm dứt.

Vì vậy, điều này có nghĩa là CLR giữ một hồ bơi thực đơn cho tất cả các ứng dụng .net đang chạy không? Ví dụ: nếu chương trình A tạo chuỗi "Kiểm tra" bằng chữ và nếu chương trình khác cố gắng tạo một chuỗi "Kiểm tra" khác, thì cùng một bản sao được sử dụng? Câu hỏi tương tự cũng áp dụng cho JVM.

Trả lời

2

CLR giữ một hồ bơi thực trong mỗi trường hợp. Nếu bạn đọc thêm xuống số MSDN link:

Nếu bạn đang cố giảm tổng dung lượng bộ nhớ mà ứng dụng của bạn phân bổ, hãy nhớ rằng việc thực hiện chuỗi có hai tác dụng phụ không mong muốn. Đầu tiên, bộ nhớ được cấp phát cho các đối tượng String được lưu trữ không có khả năng được phát hành cho đến khi thời gian chạy ngôn ngữ chung (CLR) chấm dứt.

Đối với Java, đó cũng là mỗi JVM bạn bắt đầu.

Tuy nhiên theo this article:

huyền thoại này đi theo hướng ngược lại của huyền thoại 2. Một số người luôn tin rằng chuỗi internalized ở lại trong bộ nhớ cho đến khi JVM kết thúc. Nó có thể đã đúng một thời gian dài trước đây, nhưng ngày nay các chuỗi nội bộ được thu thập rác nếu không có thêm tài liệu tham khảo cho họ. Xem bên dưới một phiên bản được sửa đổi một chút của chương trình ở trên. Nó xóa các tham chiếu đến các chuỗi nội bộ theo thời gian.Nếu bạn thực hiện theo chương trình thực hiện từ jconsole, bạn sẽ thấy rằng việc sử dụng không gian PermGen đi lên và xuống, như là Garbage Collector reclaims bộ nhớ được sử dụng bởi các chuỗi nội bộ không được rào cản.

Các phương tiện trong chuỗi thực tập Java thực sự có thể nhận được GC.

+1

Bạn có liên kết không? –

1

Không, vì không thể.
Mỗi ứng dụng chạy trong không gian bộ nhớ ảo của riêng nó. Bạn không thể chia sẻ dữ liệu giữa hai không gian bộ nhớ.
Và xem xét các chuỗi tải/dỡ. Nó sẽ trở nên rất phức tạp và bạn không bao giờ có thể loại bỏ một chuỗi.
Cũng lưu ý phần này của báo giá của bạn:

mỗi chuỗi chữ độc đáo tuyên bố hoặc tạo lập trình trong chương trình của bạn.


OK, chỉ cần đọc một chút nữa trên trang MSDN:

tham khảo của CLR đến thực tập nội trú Chuỗi đối tượng có thể tồn tại sau khi sử dụng của bạn, hoặc thậm chí miền ứng dụng của bạn, chấm dứt.

+0

Holterman - dòng từ MSDN - Đầu tiên, bộ nhớ được cấp phát cho các đối tượng String được lưu trữ sẽ không được phát hành cho đến khi thời gian chạy ngôn ngữ chung (CLR) chấm dứt. Có vẻ như nó dành cho CLR –

+0

@PK: Tôi đọc đó là "phiên bản CLR cho chương trình đó". –

0

Đối với Java, có. String literals được lưu giữ trong một pool trên mỗi JVM. Trích từ JavaDoc của String#intern(): All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

+0

chúng được thực hiện trên mỗi ứng dụng hoặc cho toàn bộ JVM? –

+0

Theo như tôi biết, có một hồ bơi cho mỗi JVM. Tuy nhiên, trong trường hợp bình thường, bạn có thể có một JVM cho mỗi ứng dụng - điều đó phụ thuộc vào định nghĩa của ứng dụng. Trong môi trường máy chủ, máy chủ ứng dụng sẽ chạy trong một JVM và có thể lưu trữ nhiều ứng dụng (phụ). – Thomas

+0

Tôi tin rằng câu hỏi dành cho một JVM đang chạy nhiều ứng dụng bằng cách sử dụng trình nạp lớp riêng biệt cho mỗi ứng dụng (ví dụ: thùng chứa servlet) cho dù có thể có nhiều nhóm nội bộ. Điều đó tương đương với việc hỏi chúng ta có thể tải java.lang.String nhiều lần với các trình nạp lớp khác nhau hay không. –

0

Khi tôi hiểu CLR là một lần cho mỗi lần chạy, không phải cho mỗi AppDomain. Từ "CLR Via C#" của Jeffrey Richter "

Lưu ý rằng trình thu thập rác không thể giải phóng các chuỗi mà bảng băm bên trong tham chiếu vì bảng băm giữ tham chiếu đến các đối tượng String đó. Các đối tượng chuỗi được tham chiếu bởi bảng băm nội bộ không thể được giải phóng cho đến khi AppDomain được dỡ bỏ hoặc quá trình chấm dứt.

Điều này cho thấy bảng tách biệt với AppDomain.

JVM không có khái niệm này nên không có sự mơ hồ. Bạn có thể có các trình nạp lớp khác nhau, nhưng thật khó để tưởng tượng bạn sẽ có các trình nạp lớp khác nhau cho Chuỗi.

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