Làm việc với các thế hệ đối tượng
Trình thu gom rác Java triển khai chiến lược thu gom rác thế hệ có thể phân loại các đối tượng theo độ tuổi.
Nhu cầu như vậy (để đánh dấu và nén tất cả các đối tượng) trong JVM có thể được gọi là không hiệu quả. Vì khi một số lượng lớn các đối tượng được phân bổ, danh sách của chúng sẽ tăng lên, dẫn đến tăng thời gian thu gom rác. Phân tích thực nghiệm các ứng dụng đã chỉ ra rằng hầu hết các đối tượng trong Java đều tồn tại trong thời gian ngắn.
Vùng bộ nhớ heap trong JVM được chia thành ba phần:
![Làm việc với các thế hệ đối tượng](https://cdn.codegym.cc/images/article/8aab6bd2-292b-4ecd-9ecc-9ee2a44d3c82/1024.jpeg)
Thế hệ trẻ
Các đối tượng mới được tạo ra bắt đầu ở thế hệ trẻ. Thế hệ trẻ được chia thành hai loại.
- Eden Space - Tất cả các đối tượng mới bắt đầu từ đây, chúng được cấp phát bộ nhớ ban đầu.
Survivor Spaces (FromSpace và ToSpace) - Các đối tượng được chuyển đến đây từ Eden sau khi sống sót sau một chu kỳ thu gom rác.
Quá trình khi các đối tượng được thu thập rác từ thế hệ trẻ hơn được gọi là sự kiện thu gom rác nhỏ.
Khi không gian của Eden chứa đầy đồ vật, một bộ sưu tập rác nhỏ sẽ được thực hiện. Tất cả các đối tượng chết được loại bỏ và tất cả các đối tượng sống được chuyển đến một trong hai không gian còn lại. GC nhỏ cũng kiểm tra các đối tượng trong không gian dành cho người sống sót và di chuyển chúng sang không gian dành cho người sống sót (tiếp theo) khác.
Hãy lấy trình tự sau đây làm ví dụ.
- Có những đối tượng thuộc cả hai loại (sống và chết) trong Eden.
- Một GC nhỏ xảy ra - tất cả các đối tượng chết đều bị xóa khỏi Eden. Tất cả các đối tượng sống được chuyển đến không gian-1 (FromSpace). Eden và Space-2 hiện đang trống.
- Các đối tượng mới được tạo và thêm vào Eden. Một số vật thể trong Eden và không gian-1 đã chết.
- Một GC nhỏ xảy ra - tất cả các vật thể chết được xóa khỏi Eden và space-1. Tất cả các đối tượng sống được chuyển đến không gian-2 (ToSpace). Eden và không gian-1 trống.
Do đó, bất cứ lúc nào, một trong những không gian sống sót luôn trống. Khi những người sống sót đạt đến một ngưỡng nhất định để di chuyển qua các không gian dành cho người sống sót, họ sẽ chuyển sang thế hệ cũ hơn.
Bạn có thể sử dụng cờ -Xmn để đặt kích thước thế hệ trẻ .
Thế hệ đi trước
Các đối tượng tồn tại trong một khoảng thời gian đáng kể (ví dụ: phần lớn thời gian tồn tại của một chương trình) cuối cùng trở thành các đối tượng cũ hơn - những người sống trăm tuổi. Nó còn được gọi là thế hệ thông thường và chứa các đồ vật đã bị bỏ lại trong Không gian sống sót trong một thời gian dài.
Ngưỡng thời gian tồn tại của một đối tượng xác định số chu kỳ thu gom rác mà nó phải trải qua trước khi được chuyển sang thế hệ cũ hơn. Quá trình khi các đối tượng được gửi đến thùng rác từ thế hệ cũ hơn được gọi là sự kiện thu gom rác chính.
Bạn có thể sử dụng các cờ -Xms và -Xmx để đặt kích thước bộ nhớ heap ban đầu và tối đa .
Bởi vì Java sử dụng bộ sưu tập rác theo thế hệ, đối tượng càng trải qua nhiều sự kiện thu thập rác thì đối tượng đó càng di chuyển xa hơn trên heap. Anh ta bắt đầu ở thế hệ trẻ và cuối cùng kết thúc ở thế hệ bình thường nếu anh ta sống đủ lâu.
Để hiểu việc thăng cấp đối tượng giữa không gian và thế hệ, hãy xem xét ví dụ sau:
Khi một vật thể được tạo ra, trước tiên nó được đặt trong không gian Eden của thế hệ trẻ.
Ngay sau khi một bộ sưu tập rác nhỏ xảy ra, các vật thể sống từ Eden sẽ được chuyển đến FromSpace. Khi quá trình thu gom rác nhỏ tiếp theo diễn ra, các vật thể sống từ cả Eden và không gian sẽ được chuyển đến ToSpace.
Chu kỳ này tiếp tục một số lần nhất định. Nếu đối tượng vẫn "đang hoạt động" sau thời điểm này, chu kỳ thu gom rác tiếp theo sẽ chuyển nó sang không gian thế hệ cũ hơn.
Tạo vĩnh viễn và metaspace
Siêu dữ liệu như các lớp và phương thức được lưu trữ trong thế hệ liên tục. JVM điền nó vào thời gian chạy dựa trên các lớp được ứng dụng sử dụng. Các lớp không còn được sử dụng có thể chuyển từ thế hệ vĩnh viễn thành rác.
Bạn có thể sử dụng cờ -XX:PermGen và -XX:MaxPermGen để đặt kích thước ban đầu và kích thước tối đa của thế hệ vĩnh viễn .
không gian meta
Kể từ Java 8, không gian PermGen đã được thay thế bằng không gian bộ nhớ MetaSpace. Việc triển khai khác với PermGen - không gian heap này hiện được thay đổi tự động.
Điều này tránh được sự cố hết bộ nhớ của ứng dụng xảy ra do kích thước hạn chế của không gian heap của PermGen. Bộ nhớ không gian siêu dữ liệu có thể được thu gom rác và các lớp không còn được sử dụng nữa sẽ tự động được dọn sạch khi không gian siêu dữ liệu đạt đến kích thước tối đa.