Tôi có một chương trình java mà là một thuật toán máy học điển hình, cập nhật các giá trị cho một số thông số của một số phương trình:chương trình Java là nhận được chậm hơn sau khi chạy một thời gian
for (int iter=0; iter<1000; iter++) {
// 1. Create many temporary variables and do some computations
// 2. Update the value for the parameters
}
Các tính toán của việc cập nhật các thông số khá phức tạp, và tôi phải tạo ra nhiều đối tượng tạm thời, nhưng chúng không được tham chiếu trong vòng lặp. Các mã trong vòng lặp là CPU chuyên sâu, và không truy cập đĩa. Chương trình này tải một tập dữ liệu tương đối lớn, do đó, tôi đã cấp bộ nhớ 10G (-Xmx10G) cho JVM, lớn hơn nhiều so với yêu cầu (đỉnh tại ~ 6G bằng lệnh "trên cùng" hoặc trình quản lý tác vụ của cửa sổ).
Tôi đã thử nghiệm trên một số máy linux (centos 6, bộ nhớ 24G) và máy cửa sổ (win7, 12G), cả hai đều có cài đặt SUN Hotspot JDK/JRE 1.8. Tôi đã không chỉ định các tham số JVM khác ngoại trừ -Xmx. Cả hai máy đều dành riêng cho chương trình của tôi.
Trên các cửa sổ, chương trình của tôi chạy tốt: mỗi lần lặp lại sử dụng thời gian chạy rất giống nhau. Tuy nhiên, thời gian chạy trên tất cả các máy centos là lạ. Ban đầu nó chạy đúng, nhưng chậm lại đáng kể (~ 10 lần chậm hơn) ở lần lặp thứ 7/thứ 8, và sau đó giữ chậm ~ 10% trong mỗi lần lặp lại sau đó.
Tôi nghi ngờ nó có thể do trình thu gom rác của Java gây ra. Vì vậy, tôi sử dụng jconsole để theo dõi chương trình của tôi. Nhỏ GC xảy ra rất thường xuyên trên cả hai máy, đó là bởi vì chương trình tạo ra nhiều biến tạm thời trong vòng lặp. Hơn nữa, tôi sử dụng "jstat -gcutil $ pid $ 1s" lệnh và bắt giữ số liệu thống kê:
Centos: https://www.dropbox.com/s/ioz7ai6i1h57eoo/jstat.png?dl=0
Window: https://www.dropbox.com/s/3uxb7ltbx9kpm9l/jstat-winpng.png?dl=0
[Sửa] Tuy nhiên, số liệu thống kê trên hai loại máy móc khác rất nhiều:
- "S1” trên cửa sổ nhảy nhanh từ 0 đến 50, trong khi thời gian lưu trú tại '0,00' trên centos
- 'E' trên cửa sổ thay đổi rất nhanh từ 0 đến 100. Như tôi pr. int stat cho mỗi giây, ảnh chụp màn hình không hiển thị tăng của nó đến 100. Trên centos, tuy nhiên, "E" tăng khá chậm về phía 100, và sau đó giảm xuống 0, và tăng trở lại.
Có vẻ như hành vi kỳ lạ của chương trình của tôi là do Java GC? Tôi mới dùng màn hình hiệu suất Java và không có ý tưởng tốt để tối ưu hóa cài đặt tham số GC. Bạn có đề nghị nào không? Cảm ơn nhiều!
Bạn có chắc chắn phải tạo nhiều đối tượng "tạm thời" trong vòng lặp không? Nếu bạn có thể kéo một số người trong số họ ra khỏi vòng lặp và tái sử dụng các trường hợp tương tự trong mỗi lần lặp lại, nó sẽ tiết kiệm một số cho rất nhiều rác (bộ sưu tập), – JimmyB
Tôi không thể di chuyển chúng ra khỏi vòng lặp. Lý do là chúng được sử dụng để lưu trữ các giá trị tạm thời cho phép tính toán học phức tạp. –
Nếu bạn không sử dụng các đối tượng bất biến, bạn thường có thể thay đổi các giá trị được lưu trữ bên trong chúng ('setX (...)', ...) mà không cần tạo một đối tượng mới. – JimmyB