Thu gom rác trong Java - GC là gì và nó hoạt động như thế nào trong JVM

Thu gom rác trong Java - GC là gì và nó hoạt động như thế nào trong JVM

Trong bài viết này, bạn sẽ tìm hiểu thêm về Công cụ thu gom rác, cách thức hoạt động và các loại GC khác nhau có sẵn trong Java và ưu điểm của chúng. Tôi cũng sẽ đề cập đến một số Trình thu gom rác thử nghiệm mới có sẵn trong các bản phát hành Java mới nhất.

Bộ sưu tập rác trong Java là gì?

Garbage Collection là quá trình lấy lại bộ nhớ không sử dụng trong thời gian chạy bằng cách phá hủy các đối tượng không sử dụng.

Trong các ngôn ngữ như C và C ++, lập trình viên chịu trách nhiệm về cả việc tạo và hủy các đối tượng. Đôi khi, lập trình viên có thể quên hủy các đối tượng vô dụng và bộ nhớ được cấp cho chúng không được giải phóng. Bộ nhớ đã sử dụng của hệ thống tiếp tục tăng lên và cuối cùng không còn bộ nhớ nào trong hệ thống để cấp phát. Các ứng dụng như vậy bị " rò rỉ bộ nhớ ".

Sau một thời điểm nhất định, không có đủ bộ nhớ để tạo các đối tượng mới và toàn bộ chương trình kết thúc bất thường do lỗi OutOfMemoryErrors.

Bạn có thể sử dụng các phương thức như free()trong C và delete()trong C ++ để thực hiện Thu dọn rác. Trong Java, việc thu thập rác diễn ra tự động trong suốt thời gian tồn tại của một chương trình. Điều này giúp loại bỏ sự cần thiết phải phân bổ bộ nhớ và do đó tránh rò rỉ bộ nhớ.

Java Garbage Collection là quá trình các chương trình Java thực hiện quản lý bộ nhớ tự động. Các chương trình Java biên dịch thành mã bytecode có thể chạy trên Máy ảo Java (JVM).

Khi các chương trình Java chạy trên JVM, các đối tượng được tạo trên heap, là một phần bộ nhớ dành riêng cho chương trình.

Trong vòng đời của một ứng dụng Java, các đối tượng mới được tạo và phát hành. Cuối cùng, một số đối tượng không còn cần thiết nữa. Bạn có thể nói rằng tại bất kỳ thời điểm nào, bộ nhớ heap bao gồm hai loại đối tượng:

  • Trực tiếp - những đối tượng này đang được sử dụng và tham chiếu từ một nơi khác
  • Đã chết - những đối tượng này không còn được sử dụng hoặc được tham chiếu từ bất kỳ đâu

Bộ thu gom rác tìm những đối tượng không sử dụng này và xóa chúng để giải phóng bộ nhớ.

Làm thế nào để bỏ qua một đối tượng trong Java

Mục tiêu chính của Garbage Collection là giải phóng bộ nhớ heap bằng cách hủy các đối tượng không chứa tham chiếu. Khi không có tham chiếu đến một đối tượng, nó được coi là đã chết và không còn cần thiết nữa. Vì vậy, bộ nhớ bị chiếm bởi đối tượng có thể được lấy lại.

Có nhiều cách khác nhau trong đó các tham chiếu đến một đối tượng có thể được giải phóng để biến nó trở thành một ứng cử viên cho Bộ sưu tập rác. Một số trong số đó là:

Bằng cách tạo một tham chiếu rỗng

Student student = new Student();
student = null;

Bằng cách gán một tham chiếu cho một

Student studentOne = new Student();
Student studentTwo = new Student();
studentOne = studentTwo; // now the first object referred by studentOne is available for garbage collection

Bằng cách sử dụng một đối tượng ẩn danh

register(new Student());

Thu gom rác hoạt động như thế nào trong Java?

Thu gom rác trong Java là một quá trình tự động. Người lập trình không cần đánh dấu rõ ràng các đối tượng cần xóa.

Việc thực hiện thu gom rác tồn tại trong JVM. Mỗi JVM có thể triển khai phiên bản thu gom rác của riêng mình. Tuy nhiên, nó phải đáp ứng đặc điểm kỹ thuật JVM tiêu chuẩn để làm việc với các đối tượng có trong bộ nhớ heap, đánh dấu hoặc xác định các đối tượng không thể truy cập và phá hủy chúng bằng nén.

Rễ thu gom rác trong Java là gì?

Người thu gom rác làm việc dựa trên khái niệm Rễ thu gom rác (GC Roots) để xác định các vật thể sống và chết.

Ví dụ về rễ Thu gom rác như vậy là:

  • Các lớp được tải bởi trình tải lớp hệ thống (không phải trình tải lớp tùy chỉnh)
  • Chủ đề trực tiếp
  • Các biến cục bộ và tham số của các phương thức hiện đang thực thi
  • Các biến cục bộ và tham số của các phương thức JNI
  • Tham chiếu JNI toàn cầu
  • Các đối tượng được sử dụng như một màn hình để đồng bộ hóa
  • Các đối tượng do JVM thu gom rác cho các mục đích của nó

Bộ thu gom rác duyệt toàn bộ đồ thị đối tượng trong bộ nhớ, bắt đầu từ các Gốc thu gom rác đó và theo sau các tham chiếu từ gốc đến các đối tượng khác.

hình-76

Các giai đoạn thu gom rác trong Java

Việc thực hiện Thu gom rác tiêu chuẩn bao gồm ba giai đoạn:

Đánh dấu các đối tượng là còn sống

Trong bước này, GC xác định tất cả các đối tượng trực tiếp trong bộ nhớ bằng cách duyệt qua biểu đồ đối tượng.

Khi GC truy cập một đối tượng, nó đánh dấu đối tượng đó là có thể truy cập và do đó tồn tại. Mọi đối tượng mà người thu gom rác ghé thăm đều được đánh dấu là còn sống. Tất cả các đối tượng không thể truy cập được từ GC Roots đều là rác và được coi là ứng cử viên để thu gom rác.

hình-82

Quét các vật chết

Sau giai đoạn đánh dấu, chúng ta có không gian bộ nhớ được chiếm bởi các đối tượng sống (đã thăm) và đã chết (không truy cập). Giai đoạn quét giải phóng các đoạn bộ nhớ có chứa các đối tượng chết này.

hình-83

Thu gọn các đối tượng còn lại trong bộ nhớ

Các vật chết đã được loại bỏ trong giai đoạn quét có thể không nhất thiết phải ở cạnh nhau. Do đó, bạn có thể có không gian bộ nhớ bị phân mảnh.

Bộ nhớ có thể được nén lại sau khi bộ thu gom rác xóa các đối tượng đã chết, để các đối tượng còn lại nằm trong một khối liền kề ở đầu heap.

Quá trình nén giúp việc cấp phát bộ nhớ cho các đối tượng mới một cách tuần tự dễ dàng hơn.

hình-85

Tập hợp Rác thế hệ trong Java là gì?

Java Garbage Collectors thực hiện một chiến lược thu gom rác thế hệ để phân loại các đối tượng theo độ tuổi.

Việc phải đánh dấu và thu gọn tất cả các đối tượng trong một JVM là không hiệu quả. Khi càng nhiều đối tượng được phân bổ, danh sách các đối tượng ngày càng lớn, dẫn đến thời gian thu gom rác lâu hơn. 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.

ObjectLifetime
Nguồn: oracle.com

Trong ví dụ trên, trục Y hiển thị số byte được phân bổ và trục X hiển thị số byte được phân bổ theo thời gian. Như bạn có thể thấy, ngày càng ít đối tượng được phân bổ theo thời gian.

Trên thực tế, hầu hết các đối tượng có tuổi thọ rất ngắn như được thể hiện bằng các giá trị cao hơn ở phía bên trái của biểu đồ. Đây là lý do tại sao Java phân loại các đối tượng thành các thế hệ và thực hiện thu gom rác cho phù hợp.

Vùng bộ nhớ heap trong JVM được chia thành ba phần:

hình ảnh-70

Thế hệ trẻ

Các đối tượng mới được tạo bắt đầu trong Thế hệ trẻ. Thế hệ trẻ được chia nhỏ thành:

  • Không gian Eden - tất cả các đối tượng mới bắt đầu ở đây và bộ nhớ ban đầu được cấp cho chúng
  • Không gian sống sót (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.

Khi đồ vật là rác được thu gom từ Thế hệ trẻ, đó là một sự kiện thu gom rác nhỏ .

Khi không gian Eden được lấp đầy bởi các đối tượng, một GC nhỏ được thực hiện. Tất cả các đối tượng đã chết sẽ bị xóa và tất cả các đối tượng sống được chuyển đến một trong những không gian sống sót. Minor GC cũng kiểm tra các đối tượng trong không gian sống sót và di chuyển chúng đến không gian còn sót lại khác.

Lấy chuỗi sau làm ví dụ:

  1. Eden có tất cả các đối tượng (sống và chết)
  2. GC nhỏ xảy ra - tất cả các vật thể đã chết đều bị loại bỏ khỏi Eden. Tất cả các đối tượng trực tiếp được chuyển đến S1 (FromSpace). Eden và S2 hiện đã trống.
  3. Các đối tượng mới được tạo và thêm vào Eden. Một số đối tượng trong Eden và S1 trở nên chết.
  4. GC nhỏ xảy ra - tất cả các vật thể đã chết đều bị loại bỏ khỏi Eden và S1. Tất cả các đối tượng trực tiếp được chuyển đến S2 (ToSpace). Eden và S1 hiện đã trống.

Vì vậy, bất cứ lúc nào, một trong những không gian sống sót luôn trống rỗng. Khi các vật thể sống sót đạt đến một ngưỡng nhất định để di chuyển xung quanh các không gian của người sống sót, chúng sẽ được chuyển đến Thế hệ cũ.

Bạn có thể sử dụng -Xmnlá cờ để đặt kích thước của Thế hệ trẻ.

Thế hệ cũ

Những vật thể tồn tại lâu cuối cùng được chuyển từ Thế hệ Trẻ sang Thế hệ Già. Đây còn được gọi là Tenured Generation, và chứa các vật thể đã tồn tại trong không gian của những người sống sót trong một thời gian dài.

Có một ngưỡng được xác định cho thời hạn sử dụng của một đối tượng, quyết định xem nó có thể tồn tại bao nhiêu chu kỳ thu gom rác trước khi chuyển sang Thế hệ cũ.

Khi các đối tượng được thu gom rác từ Thế hệ cũ, đó là một sự kiện thu gom rác lớn .

Bạn có thể sử dụng các cờ -Xmsvà để đặt kích thước của kích thước ban đầu và kích thước tối đa của bộ nhớ Heap.-Xmx

Vì Java sử dụng tính năng thu gom rác thế hệ, nên đối tượng càng tồn tại nhiều sự kiện thu gom rác, thì đối tượng càng được thăng hạng trong đống. Nó bắt đầu ở thế hệ trẻ và cuối cùng kết thúc ở thế hệ có thời hạn nếu nó tồn tại đủ lâu.

Hãy xem xét ví dụ sau để hiểu sự thăng hạng của các đối tượng giữa các không gian và các thế hệ:

Khi một vật thể được tạo ra, lần đầu tiên nó được đưa vào không gian Eden của thế hệ trẻ . Khi một bộ sưu tập rác nhỏ xảy ra, các đối tượng trực tiếp từ Eden sẽ được thăng cấp lên FromSpace . Khi lần thu gom rác nhỏ tiếp theo xảy ra, các đối tượng trực tiếp từ cả EdenFromSpace đều được chuyển đến ToSpace .

Chu kỳ này tiếp tục trong một số thời gian cụ thể. Nếu đối tượng vẫn được sử dụng sau thời điểm này, chu kỳ thu gom rác tiếp theo sẽ chuyển nó đến không gian tạo cũ .

Thế hệ vĩnh viễn

Siêu dữ liệu như các lớp và phương thức được lưu trữ trong Thế hệ vĩnh viễn. Nó được điền bởi JVM trong 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ể là rác được thu gom từ Thế hệ vĩnh viễn.

Bạn có thể sử dụng -XX:PermGen-XX:MaxPermGencờ để đặt kích thước ban đầu và tối đa của Thế hệ vĩnh viễn.

MetaSpace

Bắt đầu với Java 8, không gian bộ nhớ MetaSpace thay thế không gian PermGen . Việc triển khai khác với PermGen và không gian này của heap hiện được tự động thay đổi kích thước.

Điều này tránh được vấn đề ứng dụng hết bộ nhớ do kích thước giới hạn của không gian PermGen của heap. Bộ nhớ Metaspace có thể được thu gom rác và các lớp không còn được sử dụng có thể được tự động dọn dẹp khi Metaspace đạt đến kích thước tối đa.

Các loại bộ thu gom rác trong máy ảo Java

Tính năng thu gom rác làm cho bộ nhớ Java trở nên hiệu quả vì nó loại bỏ các đối tượng không được tham chiếu khỏi bộ nhớ heap và tạo không gian trống cho các đối tượng mới.

Máy ảo Java có tám loại trình thu gom rác. Chúng ta hãy xem xét từng chi tiết.

GC nối tiếp

Đây là cách triển khai đơn giản nhất của GC và được thiết kế cho các ứng dụng nhỏ chạy trên môi trường đơn luồng. Tất cả các sự kiện thu gom rác được tiến hành nối tiếp trong một chuỗi. Việc nén được thực hiện sau mỗi lần thu gom rác.

hình ảnh-68

Khi nó chạy, nó dẫn đến sự kiện "stop the world", nơi toàn bộ ứng dụng bị tạm dừng. Vì toàn bộ ứng dụng bị đóng băng trong quá trình thu gom rác, nó không được khuyến nghị trong trường hợp thực tế yêu cầu độ trễ thấp.

Đối số JVM để sử dụng Trình thu gom rác nối tiếp là -XX:+UseSerialGC.

GC song song

Bộ thu song song dành cho các ứng dụng có tập dữ liệu cỡ trung bình đến lớn chạy trên phần cứng đa xử lý hoặc đa luồng. Đây là cách triển khai mặc định của GC trong JVM và còn được gọi là Bộ thu thập thông lượng.

Nhiều luồng được sử dụng để thu gom rác nhỏ trong Thế hệ trẻ. Một luồng duy nhất được sử dụng để thu gom rác lớn trong Thế hệ cũ.

hình ảnh-66

Việc chạy Parallel GC cũng gây ra hiện tượng "dừng sự kiện thế giới" và ứng dụng bị đóng băng. Vì nó phù hợp hơn trong môi trường đa luồng, nó có thể được sử dụng khi nhiều công việc cần được thực hiện và việc tạm dừng dài có thể chấp nhận được, ví dụ như chạy một công việc hàng loạt.

Đối số JVM để sử dụng Trình thu gom rác song song là -XX:+UseParallelGC.

GC cũ song song

Đây là phiên bản mặc định của Parallel GC kể từ Java 7u4. Nó giống như Parallel GC ngoại trừ việc nó sử dụng nhiều luồng cho cả Thế hệ trẻ và Thế hệ cũ.

Đối số JVM để sử dụng Trình thu gom rác song song là -XX:+UseParallelOldGC.

CMS (Quét dấu đồng thời) GC

Đây còn được gọi là bộ thu tạm dừng đồng thời ở mức thấp. Nhiều luồng được sử dụng để thu gom rác nhỏ bằng cách sử dụng thuật toán tương tự như Song song. Bộ sưu tập rác chính là đa luồng, giống như Parallel Old GC, nhưng CMS chạy đồng thời cùng với các quy trình ứng dụng để giảm thiểu các sự kiện “dừng lại trên thế giới”.

hình ảnh-67

Do đó, bộ thu CMS sử dụng nhiều CPU hơn các GC khác. Nếu bạn có thể phân bổ nhiều CPU hơn để có hiệu suất tốt hơn, thì bộ thu gom rác CMS là lựa chọn tốt hơn bộ thu gom song song. Không có quá trình nén nào được thực hiện trong CMS GC.

Đối số JVM để sử dụng Bộ thu gom rác đánh dấu đồng thời là -XX:+UseConcMarkSweepGC.

G1 (Rác trước) GC

G1GC được thiết kế để thay thế cho CMS và được thiết kế cho các ứng dụng đa luồng có sẵn kích thước heap lớn (hơn 4GB). Nó song song và đồng thời giống như CMS, nhưng nó hoạt động khá khác biệt so với các bộ thu gom rác cũ hơn.

Mặc dù G1 cũng là thế hệ, nhưng nó không có vùng riêng biệt cho thế hệ già và trẻ. Thay vào đó, mỗi thế hệ là một tập hợp các khu vực, cho phép thay đổi kích thước của thế hệ trẻ một cách linh hoạt.

Nó phân vùng heap thành một tập hợp các vùng có kích thước bằng nhau (1MB đến 32MB - tùy thuộc vào kích thước của heap) và sử dụng nhiều luồng để quét chúng. Một khu vực có thể là một khu vực cũ hoặc một khu vực trẻ bất kỳ lúc nào trong quá trình chạy chương trình.

Sau khi giai đoạn đánh dấu hoàn thành, G1 biết vùng nào chứa nhiều đối tượng rác nhất. Nếu người dùng quan tâm đến thời gian tạm dừng tối thiểu, G1 có thể chọn chỉ di tản một vài khu vực. Nếu người dùng không lo lắng về thời gian tạm dừng hoặc đã nêu mục tiêu thời gian tạm dừng khá lớn, G1 có thể chọn bao gồm nhiều vùng hơn.

Vì G1GC xác định các khu vực có nhiều rác nhất và thực hiện thu gom rác trên khu vực đó trước tiên, nên nó được gọi là Garbage First.

hình ảnh-88

Ngoài Eden, Survivor và Old memory, còn có hai loại vùng khác xuất hiện trong G1GC:

  • Humongous - được sử dụng cho các đối tượng có kích thước lớn (lớn hơn 50% kích thước đống)
  • Có sẵn - không gian chưa sử dụng hoặc không được phân bổ

Đối số JVM để sử dụng G1 Garbage Collector là -XX:+UseG1GC.

Máy thu gom rác Epsilon

Epsilon là trình thu gom rác không cần làm gì (no-op) được phát hành như một phần của JDK 11. Nó xử lý cấp phát bộ nhớ nhưng không thực hiện bất kỳ cơ chế thu hồi bộ nhớ thực tế nào. Sau khi hết đống Java sẵn có, JVM sẽ tắt.

Nó có thể được sử dụng cho các ứng dụng siêu nhạy cảm với độ trễ, nơi các nhà phát triển biết chính xác dung lượng bộ nhớ của ứng dụng, hoặc thậm chí có (gần như) các ứng dụng hoàn toàn không có rác. Không khuyến khích sử dụng Epsilon GC trong bất kỳ trường hợp nào khác.

Đối số JVM để sử dụng Bộ thu gom rác Epsilon là -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC.

Shenandoah

Shenandoah là một GC mới được phát hành như một phần của JDK 12. Ưu điểm chính của Shenandoah so với G1 là nó thực hiện nhiều công việc chu trình thu gom rác đồng thời với các luồng ứng dụng hơn. G1 chỉ có thể di tản các vùng đống của nó khi ứng dụng bị tạm dừng, trong khi Shenandoah có thể di dời các đối tượng đồng thời với ứng dụng.

Shenandoah có thể thu gọn các đối tượng sống, dọn dẹp rác và giải phóng RAM trở lại hệ điều hành gần như ngay lập tức sau khi phát hiện bộ nhớ trống. Vì tất cả những điều này xảy ra đồng thời trong khi ứng dụng đang chạy, Shenandoah sử dụng nhiều CPU hơn.

Đối số JVM để sử dụng Bộ thu gom rác Epsilon là -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC.

ZGC

ZGC là một GC khác đã được phát hành như một phần của JDK 11 và đã được cải tiến trong JDK 12. Nó dành cho các ứng dụng yêu cầu độ trễ thấp (tạm dừng dưới 10 ms) và / hoặc sử dụng một đống rất lớn (nhiều terabyte).

Các mục tiêu chính của ZGC là độ trễ thấp, khả năng mở rộng và dễ sử dụng. Để đạt được điều này, ZGC cho phép một ứng dụng Java tiếp tục chạy trong khi nó thực hiện tất cả các hoạt động thu gom rác. Theo mặc định, ZGC bỏ ghi nhớ bộ nhớ không sử dụng và trả nó về hệ điều hành.

Do đó, ZGC mang đến một cải tiến đáng kể so với các GC truyền thống khác bằng cách cung cấp thời gian tạm dừng cực kỳ thấp (thường trong vòng 2ms).

figure2_600w
Nguồn: oracle.com

Đối số JVM để sử dụng Bộ thu gom rác Epsilon là -XX:+UnlockExperimentalVMOptions -XX:+UseZGC.

Lưu ý: Cả Shenandoah và ZGC đều được lên kế hoạch trở thành các tính năng sản xuất và chuyển ra khỏi giai đoạn thử nghiệm trong JDK 15.

Cách chọn công cụ thu gom rác phù hợp

Nếu ứng dụng của bạn không có yêu cầu nghiêm ngặt về thời gian tạm dừng, bạn chỉ nên chạy ứng dụng của mình và cho phép JVM chọn người thu thập phù hợp.

Hầu hết thời gian, các cài đặt mặc định sẽ hoạt động tốt. Nếu cần, bạn có thể điều chỉnh kích thước heap để cải thiện hiệu suất. Nếu hiệu suất vẫn không đạt được mục tiêu của bạn, bạn có thể sửa đổi bộ thu theo yêu cầu ứng dụng của mình:

  • Nối tiếp - Nếu ứng dụng có tập dữ liệu nhỏ (lên đến khoảng 100 MB) và / hoặc nó sẽ được chạy trên một bộ xử lý duy nhất mà không có yêu cầu về thời gian tạm dừng
  • Song song - Nếu hiệu suất ứng dụng cao nhất là ưu tiên và không có yêu cầu về thời gian tạm dừng hoặc tạm dừng một giây hoặc lâu hơn được chấp nhận
  • CMS / G1 - Nếu thời gian phản hồi quan trọng hơn thông lượng tổng thể và thời gian tạm dừng thu gom rác phải được giữ ngắn hơn khoảng một giây
  • ZGC - Nếu thời gian phản hồi là ưu tiên cao và / hoặc bạn đang sử dụng một đống rất lớn

Ưu điểm của việc thu gom rác

Có rất nhiều lợi ích của việc thu gom rác trong Java.

Trước hết, nó làm cho mã của bạn trở nên đơn giản. Bạn không phải lo lắng về chu kỳ phân bổ và giải phóng bộ nhớ thích hợp. Bạn chỉ cần ngừng sử dụng một đối tượng trong mã của mình và bộ nhớ nó đang sử dụng sẽ tự động được lấy lại vào một thời điểm nào đó.

Các lập trình viên làm việc trong các ngôn ngữ không có bộ sưu tập rác (như C và C ++) phải thực hiện quản lý bộ nhớ thủ công trong mã của họ.

Nó cũng làm cho bộ nhớ Java hiệu quả vì bộ thu gom rác loại bỏ các đối tượng không được tham chiếu khỏi bộ nhớ heap. Điều này giải phóng bộ nhớ heap để chứa các đối tượng mới.

Trong khi một số lập trình viên lập luận ủng hộ việc quản lý bộ nhớ thủ công đối với việc thu gom rác, thì tính năng thu gom rác hiện là một thành phần tiêu chuẩn của nhiều ngôn ngữ lập trình phổ biến.

Đối với các tình huống trong đó trình thu gom rác đang ảnh hưởng tiêu cực đến hiệu suất, Java cung cấp nhiều tùy chọn để điều chỉnh trình thu gom rác nhằm cải thiện hiệu quả của nó.

Các phương pháp hay nhất về thu gom rác

Tránh các trình kích hoạt thủ công

Bên cạnh các cơ chế thu gom rác cơ bản, một trong những điểm quan trọng nhất cần hiểu về tính năng thu gom rác trong Java là nó không xác định. Điều này có nghĩa là không có cách nào để dự đoán thời điểm thu gom rác sẽ diễn ra vào thời gian chạy.

Có thể đưa một gợi ý vào mã để chạy trình thu gom rác với System.gc()hoặc Runtime.gc()các phương thức, nhưng chúng không đảm bảo rằng trình thu gom rác sẽ thực sự chạy.

Sử dụng các công cụ để phân tích

Nếu bạn không có đủ bộ nhớ để chạy ứng dụng của mình, bạn sẽ gặp phải tình trạng chạy chậm, thời gian thu dọn rác lâu, sự kiện "stop the world" và cuối cùng là lỗi hết bộ nhớ. Điều này có thể chỉ ra rằng heap của bạn quá nhỏ, nhưng cũng có thể có nghĩa là bạn bị rò rỉ bộ nhớ trong ứng dụng của mình.

Bạn có thể nhận trợ giúp từ một công cụ giám sát như jstathoặc Java Flight Recorder để xem liệu việc sử dụng heap có tăng lên vô thời hạn hay không, điều này có thể chỉ ra lỗi trong mã của bạn.

Cài đặt mặc định là tốt

Nếu bạn đang chạy một ứng dụng Java nhỏ, độc lập, có lẽ bạn sẽ không cần bất kỳ loại điều chỉnh thu gom rác nào. Các cài đặt mặc định sẽ hoạt động tốt.

Sử dụng cờ JVM để điều chỉnh

Cách tốt nhất để điều chỉnh bộ sưu tập rác Java là đặt cờ trên JVM. Cờ có thể điều chỉnh bộ thu gom rác sẽ được sử dụng (ví dụ: Serial, G1, v.v.), kích thước ban đầu và tối đa của heap, kích thước của các phần heap (ví dụ: Young Generation, Old Generation), v.v.

Chọn người thu thập phù hợp

Bản chất của ứng dụng đang được điều chỉnh là một hướng dẫn ban đầu tốt cho các cài đặt. Ví dụ: Trình thu gom rác song song hiệu quả nhưng sẽ thường xuyên gây ra các sự kiện “ngừng hoạt động thế giới”, làm cho nó phù hợp hơn cho quá trình xử lý phụ trợ trong đó việc tạm dừng thu gom rác trong thời gian dài có thể chấp nhận được.

Mặt khác, trình thu gom rác CMS được thiết kế để giảm thiểu việc tạm dừng, lý tưởng cho các ứng dụng dựa trên web nơi khả năng đáp ứng là quan trọng.

Phần kết luận

Trong bài viết này, chúng ta đã thảo luận về Java Garbage Collection, cách thức hoạt động và các kiểu khác nhau của nó.

Đối với nhiều ứng dụng đơn giản, việc thu gom rác của Java không phải là điều mà một lập trình viên cần phải xem xét một cách có ý thức. Tuy nhiên, đối với các lập trình viên muốn nâng cao kỹ năng Java của mình, điều quan trọng là phải hiểu cách thức hoạt động của bộ thu gom rác Java.

Đây cũng là một câu hỏi phỏng vấn rất phổ biến, cả ở cấp cơ sở và cấp cao cho vai trò phụ trợ.

Cảm ơn bạn đã ở lại với tôi cho đến nay. Hy vọng bạn thích bài viết. Bạn có thể kết nối với tôi trên LinkedIn , nơi tôi thường xuyên thảo luận về công nghệ và cuộc sống. Ngoài ra, hãy xem một số bài viết kháckênh YouTube của tôi . Chúc các bạn đọc vui vẻ. ?