Code chạy đúng chưa đủ để một Assignment đạt yêu cầu kỹ thuật. Trong quá trình phát triển các hệ thống như quản lý bán hàng hay sinh viên, nhiều ứng dụng vẫn gặp lỗi chậm, treo hoặc sập do “rò rỉ tài nguyên”. Việc quên đóng Connection và Stream tưởng chừng đơn giản lại là nguyên nhân phổ biến khiến hệ thống mất ổn định khi vận hành thực tế.
Bạn vừa hoàn thành một hệ thống với đầy đủ chức năng, logic ổn định và chạy mượt trên máy cá nhân. Tuy nhiên, khi chạy lâu hoặc triển khai thử, ứng dụng bắt đầu chậm dần, treo máy, thậm chí crash với các lỗi liên quan đến bộ nhớ. Trong nhiều trường hợp, nguyên nhân không đến từ thuật toán mà xuất phát từ việc quản lý tài nguyên chưa đúng cách.
Nỗi ám ảnh mang tên “Resource Leak”
Hiện tượng “rò rỉ tài nguyên” (Resource Leak) xảy ra khi chương trình mở các kết nối hoặc luồng dữ liệu nhưng không đóng lại sau khi sử dụng. Ví dụ, trong một vòng lặp đọc file hoặc truy vấn cơ sở dữ liệu, mỗi lần thực hiện đều tạo ra một “đường ống” truy cập nhưng không được giải phóng.
Hậu quả là hệ thống nhanh chóng gặp các lỗi như:
java.sql.SQLException: Too many connectionsjava.io.IOException: Too many open files

Ứng dụng khi đó giống như một hệ thống bị “rò nước”, tài nguyên bị chiếm giữ liên tục cho đến khi không còn khả năng phục vụ. Các tài nguyên như Database Connection, File Stream hay Socket đều có giới hạn cụ thể do hệ điều hành và máy chủ quy định.
- Database Connection: Mỗi máy chủ chỉ cho phép một số lượng kết nối nhất định. Nếu không đóng, các kết nối sẽ chiếm hết “slot”, khiến người dùng khác không thể truy cập.
- File Stream và Socket: Hệ điều hành chỉ cấp số lượng File Descriptor hữu hạn. Khi vượt ngưỡng, ứng dụng không thể đọc/ghi thêm dữ liệu, dẫn đến lỗi nghiêm trọng.

Điểm đáng chú ý là các tài nguyên này không được quản lý trực tiếp bởi Garbage Collector. Nếu lập trình viên không chủ động đóng, chúng sẽ tồn tại cho đến khi chương trình kết thúc. Việc đóng tài nguyên không chỉ là thao tác kỹ thuật mà là yêu cầu bắt buộc để đảm bảo hệ thống vận hành ổn định. Nếu bỏ qua, ứng dụng có thể vẫn chạy trong giai đoạn đầu nhưng sẽ phát sinh lỗi khi tải tăng hoặc thời gian chạy kéo dài.
Giải pháp: Sử dụng try-with-resources
Trước Java 7, việc đóng tài nguyên thường được xử lý trong khối finally, với cấu trúc dài và dễ sai sót:

Từ Java 7 trở đi, cơ chế try-with-resources giúp tự động đóng tài nguyên, giảm rủi ro quên xử lý:

Lưu ý để Assignment vận hành ổn định
Để tránh lỗi “rò rỉ tài nguyên” và nâng cao chất lượng ứng dụng, cần lưu ý:
- Đưa tất cả đối tượng có phương thức
.close()vàotry-with-resources(Connection, Statement, ResultSet, InputStream, OutputStream, Scanner…). - Nếu đóng thủ công, thực hiện theo thứ tự ngược lại với lúc mở.
- Không phụ thuộc vào cấu hình máy cá nhân; môi trường server có giới hạn chặt chẽ hơn.
Trong phát triển phần mềm, code chạy đúng chỉ là điều kiện cần. Khả năng quản lý tài nguyên hiệu quả mới là yếu tố đảm bảo hệ thống hoạt động bền vững. Từ những bài Assignment, việc hình thành thói quen đóng tài nguyên đúng cách sẽ giúp sinh viên tiến gần hơn đến tiêu chuẩn của một lập trình viên chuyên nghiệp.
Giảng viên Trần Quang Bình
Bộ môn Ứng dụng phần mềm
FPT Polytechnic TP HCM


