Mục lục
Trong java tất cả các object được lưu trong vùng nhớ Heap. OutOfMemoryError xảy ra khi Java Virtual Machine (JVM) không thể cấp phát thêm vùng nhớ vì hết bộ nhớ, và không có thêm vùng nhớ được tạo ra bởi trình dọn rác.
Lỗi OutOfMemoryError thường xảy ra khi bạn có một số sai xót trong lập trình chẳng hạn như giữ một số lượng lớn object với một thời gian rất lâu hoặc có xử lý rất nhiều dữ liệu trong một lúc. Cũng có thể do thư viện bên thứ 3 lưu trữ lỗi etc.
Các nguyên nhân gây ra OutOfMemoryError
Java heap space
Lỗi này có thể là do ứng dụng của bạn cấu hình heap-size quá bé so với những gì ứng dụng cần. Trong trường hợp này chúng ta chỉ cần cấu hình tăng heap-size là được
Cũng có thể ứng dụng của bạn đang vô ý tham chiếu đến các object không cần thiết làm ngăn chặn trình thu gom rác dọn dẹp dẫn đến lỗi tràn bộ nhớ.
Một nguồn tiềm năng khác là ứng dụng phát sinh quá nhiều bộ nhớ finalizer – Class chứa finalize() method. Trong java nếu một class có finalize() method thì các object của class này sẽ không được trình thu gom rác dọn dẹp. Thay vào đó, sau khi quá trình thu gom rác hoàn tất, chúng sẽ được xếp vào hàng đợi được thi các finalize() method bởi damon thread. Nếu quá trình thực thi này không kịp với quá trình thêm vào hàng đợi thì chúng sẽ gây tràn bộ nhớ và dẫn đến OutOfMemoryError.
GC Overhead limit exceeded
Chỉ ra rằng trình thu gom rác đan chạy mọi lúc và chương trình đang xử lý rất chậm. Sau mỗi lần thu gom rác, nếu quá trình xử lý của java giành hơn khoảng 98% trong số đó để thu gom rác mà chỉ phục hồi ít hơn 2% của vùng nhớ heap, và quá trình này xảy ra liên tục 5 lần thì OutOfMemory sẽ được ném. Lỗi này thường xảy ra vì một lượng lớn data được lưu trữ cùng lúc trong bộ nhớ heap khiến cho nó không còn đủ không gian để phân bổ các vùng nhớ mới. Đối với trường hợp này chúng ta cần tăng heap-size hoặc cân nhắc sử dụng các phương pháp khác để tránh lưu trữ quá nhiều dữ liệu cùng lúc.
Request array size exceeds VM limit
Request array size exceeds VM limit chỉ ra rằng ứng dụng đang cố gắng sử sử dụng một array có kích thước lớn hơn vùng nhớ heap. Ví dụ vùng nhớ heap có bộ nhớ là 256Mb và bạn lại tạo một mảng có kích thước 521Mb thì OutOfMemoryError sẽ được ném ra.
Metaspace
Các metadata class (đại diện cho các class bên dưới máy ảo của java) được phân bổ trong bộ nhớ riêng gọi mà metaspace. Nếu metaspace hết bộ nhớ thì OutOfMemoryError sẽ được ném ra. Kích thước của metaspace được chỉ định bởi tham số MaxMetaSpaceSize được chỉ định trong command line. Chúng ta có thể tăng kích thước bằng cách tăng thông số của MaxMetaSpaceSize. Hoặc giảm không gian trống của vùng nhớ Heap sẽ tạo ra thêm vùng nhớ của metaspace.
Out of swap space
KLỗi này xảy ra khi kích thước của 1 requets quá lớn mà heap space của JVM có thể xử lý. Các thông tin về lỗi này sẽ được ghi vào trong 1 file log quan trọng bao gồm : thông tin về thread, process, thời gian bị lỗi , heap memory , memory map (để hiểu file log có thể tìm thêm thông tin tại đây )
Lỗi này phải sử dụng tới các tool native để sửa như:
- DTrace Tool
- Probe Providers in Java HotSpot VM
- Improvements to pmap Tool
- Improvements to pstack Tool
Lời Kết
Trên đây là các lỗi dẫn đến OutOfMemoryError chúng ta thường hay gặp phải. Ngoài ra còn các lỗi khác như Compressed class space, stack_trace_with_native_method chúng ta có thể tìm hiểu thêm tại đây.