2012-11-26 39 views
12

Tôi đang làm việc trên một dự án ERP lớn có mô hình cơ sở dữ liệu với khoảng 2100 bảng. Với "chỉ" 500 bảng được ánh xạ với Hibernate, ứng dụng được triển khai trên máy chủ web mất khoảng 3 GB bộ nhớ hoạt động.Số lượng lớn các bảng và mức tiêu thụ bộ nhớ Hibernate

Có cách nào để giảm dấu chân bộ nhớ metamodel của Hibernate khi sử dụng nhiều bảng trong một đơn vị liên tục không? Hay tôi chỉ nên từ bỏ ORM và đi với JDBC cũ đơn giản (hoặc thậm chí jOOQ)?

Hiện tại tôi đang sử dụng Hibernate 4.1.8, Spring 3.1.3, JBoss AS 7.1 và làm việc với cơ sở dữ liệu MSSQL.

Edit:

JavaMelody memory histogram output - với 2000 tạo bảng thử nghiệm mà là nhỏ hơn một chút trong phạm vi từ mô hình db gốc (do đó 'chỉ' 1,3GB bộ nhớ dành)

Chỉnh sửa 2:

Java phân tích MAT đống:

+0

Bạn có biết bao nhiêu 3GB được tiêu thụ bởi hibernate? – Kai

+0

Xét rằng với ~ 10 bảng bộ nhớ tiêu thụ là ít hơn 256MB, tôi nghĩ rằng phía bắc của nó là 2,74 GB :) – Vedran

+1

Bạn có muốn cho Batoo JPA một shot. http://batoo.jp –

Trả lời

4

tôi sẽ đề nghị để làm hồ sơ của ứng dụng trong sản xuất, dàn sử dụng java melody để tìm ra nơi hoặc những người đang tiêu thụ bộ nhớ tối đa và dựa trên kết quả profiling bạn nên quyết định những thay đổi nên được thực hiện trong ứng dụng.

Java giai điệu là rất dễ dàng để tích hợp và cấu hình và trong sản xuất, bạn có thể bật hoặc tắt bằng cách chỉ cần cập nhật web.xml

+0

Sẽ cố gắng thực hiện điều đó và cập nhật câu hỏi với kết quả vào ngày mai, cảm ơn đề xuất. – Vedran

+0

Đã thêm biểu đồ bộ nhớ từ JavaMelody. – Vedran

+0

không thể tạo ra nhiều từ biểu đồ, nhưng bạn nên tìm kiếm lớp nào của bạn tiêu thụ bộ nhớ tối đa và sau đó kiểm tra xem ai đang giữ chúng. không chắc chắn nó sẽ dễ dàng để tìm ra cách sử dụng bộ nhớ và nút cổ chai của nó dễ dàng. –

5

Một phiên Hibernate mở sẽ có xu hướng tích luỹ đối tượng vì nó được sử dụng. Đây không phải là rò rỉ bộ nhớ; một phiên ngủ đông được thiết kế để được sử dụng một lần cho một yêu cầu và nó lưu trữ các đối tượng liên tục (tức là trong phiên), cũng như các truy vấn và dữ liệu khác. Nếu bạn gọi số session.toString(), bạn sẽ thấy một danh sách các đồ vật trong phiên.

Nếu bạn làm việc với số lượng lớn các đối tượng, hãy xem xét xử lý các đối tượng theo lô. Bạn có thể gọi session.clear() sau mỗi lô để xóa dữ liệu được lưu trong bộ nhớ cache và các đối tượng liên tục khỏi phiên và giảm dấu chân bộ nhớ của phiên (đôi khi đáng kể).

Sau khi gọi session.clear(), lưu ý rằng các đối tượng được tải trước khi cuộc gọi này sẽ hoàn nguyên về trạng thái tách rời và không còn hoạt động cho phiên hiện tại nữa.

Bạn cũng có thể sử dụng tìm nạp lười để tối ưu hóa lượng dữ liệu hibernate phải tải để xử lý một thao tác nhất định. Bạn có thể đọc thêm về điều này trong tài liệu ngủ đông. Tôi khuyên bạn nên bật tính năng ghi nhật ký SQL của hibernate và kiểm tra xem liệu hibernate có đang kéo dữ liệu trở lại mà nó không cần đến hay không.

Bạn cũng có thể cấu hình hibernate để thu thập số liệu thống kê có thể giúp bạn:

sessionFactory.getStatistics().setStatisticsEnabled(true); 
1

mục đích đối tượng ngủ đông của bạn là gì, ngủ đông chỉ thích hợp cho Curd (Tạo, cập nhật, đọc, xóa), nhưng không thích hợp cho việc tính toán.cho bất kỳ mục đích tính toán nào (đặc biệt là bảng chéo), sử dụng quy trình lưu trữ và ibatis cùng nhau tốt hơn.

+1

Yêu cầu của dự án là nhắm mục tiêu nhiều RDBMS (tức là Oracle, PGSQL, MSSQL, MySQL ...), thật đáng buồn làm cho ibatis trở thành một tùy chọn rất đắt tiền (RẤT!). Ngoài ra, tôi rất không đồng ý rằng Hibernate chỉ thích hợp cho các hoạt động CRUD. – Vedran

Các vấn đề liên quan