Heap dump trong Java

Chào mừng các bạn đã quay trở lại với thachleblog. Bài viết hôm nay mình sẽ chia sẻ một kỹ thuật hay nói chính xác hơn một cách để các bạn có thể theo dõi được là khi chương trình của chúng ta chạy, nó sẽ chiếm bộ nhớ như thế nào và những object nào được tạo ra nhiều nhất. Việc này để làm gì thì các bạn xem tiếp ở phần dưới nhé, cái này là mở đầu thôi, hehe.

Đối với các bạn làm backend như mình thì rất có thể sẽ gặp một tình huống chỉ xảy ra trên môi trường production đó là khi ứng dụng của chúng ta chạy một thời gian, nó sẽ ngốn rất nhiều bộ nhớ và thỉnh thoảng warning dù cho chúng ta có khai báo maxHeap cho ứng dụng là bao nhiêu đi nữa. (Các project của mình thường khai báo 4 – 8G cho maxHeap).

Đến lúc này thì sẽ xảy ra lỗi cực kỳ nghiêm trọng, ứng dụng sẽ không thể chạy được nữa do thiếu bộ nhớ. Cách giải quyết tạm thời cho vấn đề này là restart lại chương trình và tăng maxHeap cho ứng dụng. Tuy nhiên, cách làm này không giải quyết được vấn đề triệt để. Vì nếu vấn đề nằm ở việc code của ứng dụng không giải phóng tốt bộ nhớ thì lỗi này sẽ lại tiếp tục xảy ra trong một ngày không xa.

Có một cách nữa là chúng ta sẽ cho chương trình tự động restart sau một khoảng thời gian nhất định để giải phóng vùng nhớ, cách này có vẻ khả thi hơn. Tuy nhiên nếu ứng dụng sử dụng cache local,  restart sẽ ảnh hưởng đến performance do lúc ban đầu warm up cache.

Và nếu bạn nghi ngờ là ứng dụng chưa được tốt trong việc quản lý bộ nhớ thì bạn có thể kiểm tra bằng cách gọi dump heap. Bằng cách này bạn có thể xem được là tại lúc ứng dụng bị đầy bộ nhớ, object nào là được tạo nhiều nhất và chiếm bộ nhớ nhiều nhất, từ đó phân tích và tối ưu code.

Dump heap chỉ là thuật ngữ chỉ “hình ảnh” toàn bộ các object của chương trình được tạo ra khi chương trình chạy tại một thời điểm trên bộ nhớ. Và để “chụp” hình ảnh này thì java đã hỗ trợ tool mà mình rất hay dùng đó là jmap (có rất nhiều cách để dump heap)

Đầu tiên bạn cần xác định pid của ứng dụng bằng cách sử dụng cmd:

ps -ef|grep "tên ứng dụng"

Ứng dụng của mình tên là pkg999c, cái này config trong file build

Sau khi có được pid của ứng dụng thì bạn chỉ việc chạy lện dump của jmap

jmap -dump:live,file=path/name. pid

Ở lệnh trên mình đã lấy được pid của chương trình pkg999c3443

Đến lúc này, chúng ta chỉ việc sử dụng VisualVM để load file dump vừa được tạo và xem thống kê object được tạo nhiều nhất và chiếm nhiều vùng nhớ nhất, từ đó tối ưu chương trình (nếu cần thiết)

Hình ảnh về các instances của ứng dụng pkg999

Vừa rồi là phần trình bày của mình về cách để dump heap một ứng dụng trong Java, thật là đơn giản phải không nào? Các bạn có thể thử ngay với một chương trình đơn giản để hiểu hơn nhé.

Bài viết của mình đến đây là hết nhé, thỉnh thoảng mình sẽ share những gì mình học được hoặc những kinh nghiệm trong quá trình làm việc, nên bạn nào có hứng thú với các bài viết của mình thì hãy follow page để nhận thông báo khi có bài viết mới nhé. Chào thân ái và hẹn gặp lại.

Tham khảo thêm

https://www.javaworld.com/article/2072864/heap-dump-and-analysis-with-visualvm.html