cuốn sách gpt4 ai đã làm

08. Công cụ điều chỉnh thực hành 1 (jstat)

In lại Tác giả: Đường đến ông chủ Thời gian cập nhật: 2024-01-23 20:33:43 28 4
mua khóa gpt4 Nike

1. Sử dụng nền

Nói chung, các công ty vừa và lớn sẽ có hệ thống giám sát ứng dụng của riêng họ, chẳng hạn như Zabbix nguồn mở, Open-Falcon, Prometheus, v.v. Một số công ty cũng có thể triển khai hệ thống giám sát hoặc cảnh báo của riêng họ; nếu xảy ra bất thường (chẳng hạn như sử dụng CPU cao, FullGC thường xuyên, v.v.), cảnh báo sẽ được gửi trực tiếp đến quản trị viên qua SMS, email hoặc công cụ IM.

Nhưng đối với các nhà phát triển, họ không nên dựa vào các hệ thống giám sát này; việc sử dụng thành thạo các công cụ dòng lệnh khác nhau để khám phá, định vị và giải quyết các vấn đề trên dòng lệnh là một kỹ năng cần thiết đối với một kỹ sư xuất sắc.

Do đó, chúng ta cần nắm vững một số công cụ giám sát jvm dòng lệnh đơn giản, dễ sử dụng, hiệu quả và thiết thực để giúp cho việc phát triển và giải quyết vấn đề hàng ngày của chúng ta hiệu quả hơn.

2. Giới thiệu và sử dụng jstat

jstat là một lệnh tự động rất hữu ích trong JDK. Nó có thể hiển thị mức sử dụng bộ nhớ của Eden, Survivor, thế hệ cũ, v.v. của JVM hiện đang chạy hệ thống. Nó cũng có thể hiển thị trạng thái thực thi và thời gian tiêu thụ của Young CG, Full. GC, v.v.

Thông qua các chỉ báo này, chúng ta có thể dễ dàng phân tích trạng thái vận hành hệ thống hiện tại, trạng thái GC, việc phân bổ bộ nhớ có hợp lý hay không, v.v.

2.1 jstat -gc Giới thiệu PID

Thực thi lệnh jps (Baidu cho những ai chưa hiểu) trên máy chủ và bạn có thể thấy các tiến trình java hiện đang chạy trên máy chủ. Mỗi tiến trình sẽ có một ID tiến trình ở phía trước nó, đó là PID ở đây.

Sau đó sử dụng PID này để thực thi jstat -gc PIDĐặt hàng:
jstat -gc PID: Chỉ có thể lấy được một hàng chỉ báo về hoạt động của hệ thống hiện tại;
jstat -gc PID 1000 10: Được thực hiện cứ sau 1000 mili giây (1 giây), tổng cộng 10 lần;
jstat -gc PID 1000: Thực thi mỗi giây một lần và thực thi liên tục;

Ví dụ:  

  • S0C: Kích thước của khu vực From Survivor;
  • S1C: Kích thước của khu vực To Survivor;
  • S0U: Kích thước bộ nhớ hiện được sử dụng bởi khu vực From Survivor;
  • S1U: Kích thước bộ nhớ hiện đang được sử dụng bởi khu vực To Survivor;
  • EC: diện tích khu Eden;
  • EU: Kích thước bộ nhớ hiện đang được sử dụng ở khu vực Eden;
  • OC: quy mô của thế hệ cũ;
  • OU: Kích thước bộ nhớ hiện đang được sử dụng ở thế hệ cũ;
  • MC: Kích thước của vùng phương thức (thế hệ cố định, vùng siêu dữ liệu);
  • MU: Kích thước bộ nhớ hiện đang được sử dụng của vùng phương thức (vùng tạo vĩnh viễn, vùng siêu dữ liệu);
  • YGC: số lượng GC trẻ mà hệ thống đã chạy cho đến nay;
  • YGCT: GC trẻ tốn nhiều thời gian;
  • FGC: Số lượng GC đầy đủ mà hệ thống đã chạy cho đến nay;
  • FGCT: Tiêu thụ toàn bộ thời gian GC;
  • CGC: Số lượng GC đồng thời (JDK11)
  • CGCT: Tiêu thụ thời gian GC đồng thời (JDK11)
  • GCT: tổng thời gian thực hiện của tất cả các GC;

Tại thời điểm này, nếu bạn có nền tảng JVM tốt hơn, bạn sẽ có thể nhận thấy: dựa trên các chỉ báo này, chúng tôi có thể hoàn thành nhiều hoạt động giám sát JVM khác nhau;
Lệnh này cũng Lệnh jstat đầy đủ, thông dụng và thiết thực nhất.

2.2 Các lệnh jstat khác

  • jstat -gccapacity PID: Phân tích bộ nhớ heap;
  • jstat -gcnew PID: phân tích GC thế hệ trẻ (TT và MTT: tuổi và tuổi tối đa của các đối tượng trong thế hệ trẻ)
  • jstat -gcnewcapacity PID: phân tích bộ nhớ thế hệ trẻ;
  • jstat -gcold PID: phân tích GC thế hệ cũ;
  • jstat -gcoldcapacity PID: phân tích bộ nhớ thế hệ cũ;
  • jstat -gcmetacapacity PID: Phân tích bộ nhớ vùng siêu dữ liệu;

Nhìn thoáng qua bạn có thể biết rằng các lệnh này dùng để phân tích và thống kê của một khu vực riêng biệt. Bạn có thể tự mình sử dụng tất cả chúng.

2.3 jstat -gc sử dụng PID

Đầu tiên sử dụng một đoạn mã để mô phỏng GC:

/** * tùy chọn jvm: * -Xms20m -Xmx20m -Xmn5m -XX:SurvivorRatio=8 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC */ public class JstatDemo { public static void main(String[] args) ném InterruptedException { TimeUnit .SECONDS.sleep(15); // Thuận tiện để chờ thực thi jps, lệnh jstat... for (int i = 0; i < 10; i++) { call(); } } void call() ném InterruptedException { List list = new ArrayList<>(); (int j = 0; j < 4; j++) { list.add(byte mới[1024 * 1024]); TimeUnit.SECONDS.sleep(1 } } }

Hãy chú ý đến các tham số jvm ở trên mã: không gian heap 20m, thế hệ mới 5m (tỷ lệ diện tích Eden là 4m), thế hệ cũ 15m.

Như mong đợi, việc thực thi mã sẽ là:
Trong vòng lặp for của phương thức call(), 1m đối tượng được tạo ra mỗi giây Vì diện tích Eden là 4m, Young GC sẽ xuất hiện khi đối tượng thứ 4 được tạo ra (khi đó YGC sẽ xuất hiện cứ sau 4 giây).
Và các đối tượng được tạo bởi tham chiếu danh sách sẽ được sử dụng, do đó chúng không phải là đối tượng rác tại thời điểm này và sẽ không bị GC loại bỏ trực tiếp;
Diện tích Survivor chỉ 0,5m, chắc chắn không đủ để lưu trữ các đối tượng 3M còn sót lại của Young GC, vì vậy lúc này các đối tượng 3M sẽ bước vào thế hệ cũ thông qua đảm bảo phân bổ;

Kích thước của thế hệ cũ là 15m, nhưng có những quy tắc so sánh cụ thể về đảm bảo phân bổ không gian (nếu chưa biết, bạn có thể đọc bài viết trước) nên Full GC sẽ không xảy ra cho đến khi thế hệ cũ thực sự gần đầy; nó có thể là khoảng 10m, thậm chí một nửa thời gian xảy ra Full GC (khi Full GC xảy ra, danh sách sẽ trở thành một đối tượng rác và có thể được tái chế)
Lý tưởng nhất, giả sử rằng Full GC xảy ra dựa trên 10m, các đối tượng 3M sẽ vào thế hệ cũ cứ sau 3 giây. Khi vào thế hệ cũ lần thứ tư, thế hệ cũ không đủ không gian và lần này sẽ xảy ra Full GC; (từ Việc tính toán bắt đầu khi thế hệ cũ được nhập lần đầu tiên. Tại thời điểm này, 3 giây đã được sử dụng ở thế hệ mới);
Sau đó, GC đầy đủ sẽ xuất hiện ở thế hệ cũ cứ sau 12 giây;

Tất nhiên, đây là những tình huống lý tưởng. Trong thực tế, chúng sẽ bị ảnh hưởng bởi nhiều yếu tố như hiệu suất máy và phiên bản JDK, dẫn đến việc thực thi khác với tình huống lý tưởng.

Tình trạng thực hiện:
 

  • Dòng 3: Mã chính thức bắt đầu thực thi;

  • Bạn có thể thấy cột EU, là khu vực Eden, được phân bổ với tốc độ 1M mỗi giây;

  • Hàng 6: Cột EU thay đổi từ 3498 thành 1024;

  • Nghĩa là, kích thước của khu vực Eden được đề cập ở trên là 4m. Sau 3 giây, 3m được sử dụng. Khi tiếp tục, nó không thể được giải phóng và nhìn vào cột YGC thay đổi từ 0 thành 1;

  • Và cột OU đã thay đổi từ 0 thành 3074, là đối tượng 3M bước vào thế hệ cũ thông qua đảm bảo phân bổ;

  • Dòng 9: Trong 3 giây thứ hai, YGC lại xuất hiện và cột YGC thay đổi từ 1 thành 2;

  • Cột OU đã thay đổi từ 3074 thành 5407 (Điều này không được quảng bá như chúng tôi mong đợi. Nó sẽ được quảng bá thêm 3m như mong đợi, nhưng nó không ảnh hưởng đến việc phân tích jstat)

  • Dòng 18: Trong 3 giây thứ năm, YGC lại xuất hiện và cột YGC thay đổi từ 4 thành 5;

  • Cột OU thay đổi từ 6431 thành 3346, có nghĩa là GC đầy đủ đã xảy ra và các đối tượng ở thế hệ cũ đã được tái chế (ở đây chúng tôi không tái chế khoảng 10m như chúng tôi mong đợi, nhưng nó không ảnh hưởng đến việc phân tích jstat)

  • Cột FGC đã thay đổi từ 0 thành 2 và FGC xảy ra trực tiếp hai lần ở đây...

  • Dòng 31: Trong 3 giây thứ chín, FGC lại xuất hiện và cột FGC thay đổi từ 2 thành 4;

Ở đây cũng có thể thấy rằng tình huống thực thi thực tế khá khác so với tình huống phân tích logic.

3. Chú ý đến các chỉ số và phân tích tính toán

3.1 Chú ý đến các chỉ số

Đối với một hệ thống ứng dụng chạy trực tuyến, chúng ta cần chú ý điều gì về JVM? Tôi nghĩ chúng là các loại chỉ số sau:

1. Tốc độ tăng trưởng của đối tượng (có bao nhiêu đối tượng bộ nhớ được tạo ra mỗi giây hoặc phút);
2. Tần suất xuất hiện và tốn thời gian của YoungGC;
3. Sau mỗi YoungGC, có bao nhiêu đối tượng có thể tồn tại;
4. Sau mỗi YoungGC, có bao nhiêu đối tượng bước vào thế hệ cũ;
5. Tốc độ phát triển của các đối tượng ở thế hệ cũ;
6. Tần suất xuất hiện và tốn thời gian của FullGC;

3.2 Phân tích tính toán

Vậy chúng ta sử dụng lệnh jstat để lấy các chỉ số này như thế nào?

1. Tốc độ tăng trưởng của đối tượng:;

  • Giải thích: Chỉ báo này cũng là điều đầu tiên chúng ta thường cần biết về JVM, tức là khi hệ thống chạy, mỗi giây sẽ có bao nhiêu đối tượng được phân bổ trong khu vực Eden của thế hệ mới;

  • Tính toán: Thực hiệnjstat -gc PID 1000 10Đặt hàng;

    • Giả sử rằng số liệu thống kê trong giây đầu tiên cho thấy khu vực Eden sử dụng 200M, giây thứ hai cho thấy khu vực Eden sử dụng 210M và giây thứ ba cho thấy khu vực Eden sử dụng 219M...
    • Bằng cách tương tự, chúng ta có thể tính toán đại khái rằng hệ thống hiện tại thêm khoảng 10 triệu đối tượng mỗi giây;
    • Bạn cũng có thể linh hoạt điều chỉnh việc sử dụng theo hệ thống của mình. Ví dụ: nếu tải hệ thống rất thấp và có thể không có yêu cầu mỗi giây, bạn có thể thay đổi khoảng thời gian trên 1 giây thành 1 phút hoặc thậm chí 10 phút, v.v. ; sau đó đếm hệ thống trong 1 phút hoặc 10 phút.
    • Ngoài ra, hệ thống có thể có hai trạng thái là chu kỳ cao điểm và chu kỳ hàng ngày và việc thống kê phải được tiến hành riêng biệt; 2. Tần suất xuất hiện và mức độ tiêu tốn thời gian của YoungGC:;
  • Giải thích: Trên thực tế, nếu biết tốc độ tăng trưởng của đối tượng, bạn có thể dễ dàng tính toán tần suất Young GC xảy ra dựa trên kích thước bộ nhớ của vùng Eden mà bạn đặt;

    • Ví dụ: nếu kích thước khu vực Eden của bạn là 800M và 10M đối tượng được tạo ra mỗi giây thì GC trẻ sẽ xảy ra khoảng 80 giây một lần;
  • Tính toán: Tất nhiên chúng ta cũng có thể thực hiệnjstat -gc PID 1000Đặt hàng đo thực tế;

    • Chỉ cần quan sát cột YGC được thêm vào bao nhiêu giây là bạn sẽ biết Young GC thực sự xảy ra bao nhiêu giây;
    • Đối với mức tiêu thụ thời gian trung bình của Young GC: Cột YGCT sau cột YGC hiển thị tổng thời gian tiêu thụ của số YGC hiện tại;
      Ví dụ: sau khi hệ thống chạy được 24 giờ, YGC xảy ra 100 lần và tổng thời gian YGCT là 200ms. Trung bình, mỗi Young GC mất khoảng 2 mili giây;
    • Nói cách khác, trong hệ thống của bạn, mỗi Young GC sẽ tạm dừng 2 mili giây (không đáng kể); 3. Sau mỗi YoungGC, có bao nhiêu đối tượng có thể tồn tại và bước vào thế hệ cũ:;
  • Giải thích: Chúng tôi không thể trực tiếp xem có bao nhiêu đối tượng có thể tồn tại sau mỗi Young GC, nhưng chúng tôi có thể tính toán;

    • Chúng tôi đã thử nghiệm nó trước đây và Young GC xảy ra cứ sau 80 giây;
  • Tính toán: Sau đó chúng ta sẽ thực hiện vào lúc này jstat -gc PID 80000 10, thực hiện 80 giây một lần, thực hiện liên tục 10 lần;

    • Tại thời điểm này, bạn có thể quan sát thấy rằng sau khi GC trẻ xảy ra cứ sau 80 giây, các đối tượng trong khu vực Eden, khu vực Người sống sót và thế hệ cũ sẽ thay đổi vào thời điểm này;
    • Ví dụ, trong khu vực Eden 800M, sau khi xảy ra GC trẻ, trong trường hợp bình thường phải có rất ít đối tượng trong khu vực Eden, chẳng hạn như còn lại hàng chục M (mới được tạo ra);
      Nhưng đối với những đồ vật còn sống sót, họ sẽ vào khu vực Người sống sót hoặc thế hệ cũ;
    • Bao nhiêu vật bước vào tuổi già: Chúng ta có thể biết kích thước của các đối tượng bước vào thế hệ cũ sau mỗi Young GC thông qua sự thay đổi kích thước của cột OU, ví dụ: 10M đối tượng bước vào thế hệ cũ;
    • Tốc độ phát triển của các đối tượng ở thế hệ cũ: GC trẻ xảy ra cứ sau 80 giây và 10M đối tượng bước vào thế hệ cũ, có nghĩa là tốc độ tăng trưởng đối tượng ở thế hệ cũ là 10M cứ sau 80 giây;
    • Có bao nhiêu đồ vật còn sống: Và thông qua việc thay đổi kích thước của cột S1U, chúng ta có thể biết được kích thước của các đối tượng đi vào khu vực Survivor sau mỗi Young GC; (bước vào khu vực thế hệ cũ + Người sống sót);
    • Ngoài ra, các đối tượng ở thế hệ cũ không nên tiếp tục phát triển nhanh chóng, hoặc thậm chí hiếm khi phát triển trong điều kiện hoạt động bình thường vì các hệ thống thông thường không có nhiều đối tượng tồn tại lâu dài, miễn là việc phân bổ bộ nhớ ở thế hệ mới là hợp lý; , các đối tượng trong thế hệ cũ Tăng trưởng sẽ ở mức tối thiểu; 4. Tần suất xuất hiện và thời gian sử dụng FullGC:;
  • Giải thích: Cũng giống như tần suất xuất hiện và mức tiêu tốn thời gian của Young GC, nếu bạn biết tốc độ tăng trưởng của các đối tượng thế hệ cũ và kích thước bộ nhớ thế hệ cũ mà bạn đặt, bạn cũng có thể dễ dàng tính toán tần suất xảy ra Full GC;

    • Ví dụ: nếu kích thước của thế hệ cũ cũng là 800M và sau đó cứ sau 80 giây lại có 10 triệu đối tượng bước vào thế hệ cũ thì GC đầy đủ sẽ xảy ra cứ sau 6400 giây, tức là khoảng 2 giờ;
    • Mức tiêu thụ thời gian trung bình của Full GC cũng có thể được tính thông qua cột FGCT sau cột FGC, là tổng thời gian tiêu thụ của số lượng FGC hiện tại đã xảy ra;
    • Ví dụ: nếu FGC được thực thi tổng cộng 10 lần thì tổng thời gian là 2 giây, nghĩa là mỗi lần Full GC mất khoảng 0,2 giây;

Việc thu thập và phân tích các chỉ số này có thể đạt được bằng cách sử dụng lệnh jstat; và kết hợp với nguyên tắc hoạt động của jvm, việc nắm bắt trạng thái hoạt động của jvm trong hệ thống trực tuyến sẽ dễ dàng hơn và cũng có thể tiến hành phân tích có mục tiêu về hoạt động cụ thể trạng thái tối ưu hóa jvm.

28 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress