JavaRush /Blog Java /Random-VI /Nghỉ giải lao #88. Sức mạnh của siêu dữ liệu: cách làm vi...

Nghỉ giải lao #88. Sức mạnh của siêu dữ liệu: cách làm việc với mã spaghetti. Thu gom rác trong Java - cách thức hoạt động và ưu điểm của nó là gì

Xuất bản trong nhóm

Sức mạnh của siêu dữ liệu: cách làm việc với mã spaghetti

Nguồn: Hackernoon Tất cả chúng ta đều cố gắng sử dụng các phương pháp tiếp cận phổ biến và các mẫu đã biết để tạo ra một ứng dụng với nỗ lực tối thiểu và tác động tối đa. Chúng tôi có các thư viện tuyệt vời và các khung công tác mạnh mẽ để thực hiện các hoạt động thường ngày cho chúng tôi. Chúng tôi sử dụng tất cả điều này để chỉ tập trung vào logic kinh doanh. Tuy nhiên, việc theo đuổi này thường dẫn chúng ta đến mã spaghetti, đặc biệt là khi thực hiện một chức năng mà không có giải pháp làm sẵn cho nó. Trong bài viết này, tôi muốn chia sẻ với bạn một công cụ mạnh mẽ mà theo kinh nghiệm của tôi, không phải nhà phát triển nào cũng đánh giá cao. Công cụ này có mặt trong hầu hết các ngôn ngữ lập trình và nó thường được sử dụng trong nhiều framework - chú thích. Nghỉ giải lao #88.  Sức mạnh của siêu dữ liệu: cách làm việc với mã spaghetti.  Thu gom rác trong Java - cách thức hoạt động và ưu điểm của nó - 1

Bạn có thích spaghetti không?

Hãy xem một ví dụ mà tôi đã gặp cách đây vài năm. Tôi cần phân tích bảng tính Excel để đưa dữ liệu được phân tích cú pháp vào cơ sở dữ liệu. Tôi cũng muốn thu thập một số dữ liệu từ cơ sở dữ liệu và tạo bảng tính. Để triển khai, tôi đã sử dụng thư viện Java nổi tiếng - Apache POI. API của thư viện giúp công việc của bạn dễ dàng hơn vì nó cho phép bạn tạo trang tính, hàng, ô và các thành phần khác theo cách thủ công. Điều này rất tốt, nhưng khi cần tạo nhiều bảng tính Excel khác nhau, mã sẽ hoàn toàn không thể đọc được và không thể hỗ trợ. Kết quả là, như thường lệ, phiên bản đầu tiên của ứng dụng hóa ra lại rất tệ. Việc triển khai bao gồm một lớp dữ liệu biểu thị một chuỗi có tất cả các trường cần thiết để phân tích cú pháp. Ngoài ra còn có một trình phân tích cú pháp trong đó các trường Excel được phân tích cú pháp từng ô và đặt vào một phiên bản lớp dữ liệu mới được tạo. Lúc đầu, chương trình hoạt động rất tốt và làm được những gì được yêu cầu. Các vấn đề bắt đầu xảy ra khi đến lúc phải thực hiện một số sửa đổi; mã không được đọc. Ngay cả tôi, người viết mã này, cũng không thể tìm được nơi thích hợp để đặt các dòng mới nhằm triển khai chức năng mới mà tôi cần.

Cứu hộ trong chú thích

Đã lưu ứng dụng từ mã spaghetti chú thích này. Để loại bỏ mã không được hỗ trợ, tôi cần di chuyển logic để xác định cột nào cần phân tích cú pháp, loại dữ liệu mà ô chứa và mọi thứ khác đến một vị trí khác. Để làm điều này, tôi đã tạo một chú thích trong đó tôi chỉ định tên cột cho từng trường lớp. Trong chú thích, tôi cũng đã thêm một biến cho phép bạn chọn màu và phông chữ của ô. Do đó, mã trong lớp phân tích cú pháp đã giảm đáng kể. Chỉ có một bộ xử lý tự động tạo bảng tính dựa trên các tham số lấy từ chú thích. Đó là một chiến thắng. Sau đó, để thực hiện bất kỳ thay đổi nào đối với ứng dụng, tôi chỉ cần tạo một lớp có chú thích. Giải pháp này gợi nhớ đến thư viện Jackson, thư viện này phân tích cú pháp JSON bằng cách sử dụng các chú thích và tôi nghĩ không cần phải nói Jackson hoặc các thư viện tương tự tiện lợi như thế nào.
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnExcel {

    String name() default "";

    int position();

    ExcelColumnDataFormat cellTypePattern() default ExcelColumnDataFormat.NONE;

    IndexedColors cellColor() default IndexedColors.AUTOMATIC;

    ExcelTotalFormula total() default ExcelTotalFormula.NONE;

}
ColumnExcel columnExcel = field.getAnnotation(ColumnExcel.class);
Khi ứng dụng phát triển, nó nhận được một chú thích mới có thể được sử dụng để tạo một ô trong bảng tính có hàm bên trong. Có thể nhân, trừ nhiều trường khác nhau và có thể sử dụng bất kỳ hàm Excel phổ biến nào. Tôi cũng đã thêm một hàng tổng để hiển thị tổng theo cột. Và tôi đã làm tất cả điều này chỉ bằng cách sửa đổi một chút trình phân tích cú pháp chính và chỉ cần thêm chú thích vào các lớp.
@ColumnExcel(
            name = "Views",
            position = 4,
            total = ExcelTotalFormula.SUM)
    private BigDecimal variableC;

    @ColumnExcelFormula(
            name = "Conversion",
            position = 5,
            cellTypePattern = CellDataTypeFormatPattern.PERCENTAGE
    )
    public String variableD(int rowNumber) {
        return new CellAddress(rowNumber, 4).formatAsString() + "*"
		+ new CellAddress(rowNumber, 2).formatAsString();
    }

    @ColumnExcelTotalFormula(position = 4, cellTypePattern = CellDataTypeFormatPattern.RUR)
    public static String getVariableCTotalFormula(int firstRowNum, int lastRowNum) {
        return "SUM( " + new CellAddress(firstRowNum, 4).formatAsString() + ":"
		+ new CellAddress(lastRowNum, 4).formatAsString() + ")";
    }

Thu gom rác trong Java - cách thức hoạt động và ưu điểm của nó là gì

Nguồn: Dev.to Garbage Collection có nghĩa là phá hủy hoặc dọn dẹp các đối tượng không sử dụng trong bộ nhớ. Java xử lý việc phân bổ bộ nhớ một cách tự động vì khi một đối tượng được tạo, nó sẽ sử dụng một số bộ nhớ trên heap. Nghỉ giải lao #88.  Sức mạnh của siêu dữ liệu: cách làm việc với mã spaghetti.  Thu gom rác trong Java - cách thức hoạt động và ưu điểm của nó - 2

Làm thế nào nó hoạt động?

Trước Java, ngôn ngữ lập trình phổ biến nhất là C hoặc C++. Nếu bạn nói những ngôn ngữ này thì bạn nên biết rằng chúng quản lý bộ nhớ của chúng theo cách thủ công. Ví dụ: C có các phương thức như calloc() , malloc()realloc() sẽ cho phép bạn sử dụng bộ nhớ đệm. Bạn phải xác định lượng bộ nhớ bạn cần cho chương trình của mình và chỉ định API này được gọi là gì. Sau đó, bạn có thể lấy bộ nhớ đệm để tạo nút danh sách liên kết hoặc thứ gì khác. Khi chương trình của bạn kết thúc, tại một thời điểm nào đó, bạn cũng có trách nhiệm dọn dẹp bộ nhớ đó. Vì vậy, một ứng dụng lớn được viết bằng C liên tục phân bổ bộ nhớ đệm và đôi khi quên xóa nó. Điều này cuối cùng gây ra rò rỉ bộ nhớ và nhiều vấn đề trong ứng dụng. Không giống như C và C++, ngôn ngữ Java có tính năng quản lý bộ nhớ tự động thông qua một luồng gọi là trình thu gom rác. Mục đích chính của nó là giải phóng bộ nhớ heap bằng cách phá hủy các đối tượng không thể truy cập được. Trình thu gom rác luôn chạy ở chế độ nền.

Các đối tượng không thể truy cập trong Java là gì?

Khi nào một đối tượng có cơ hội bắt đầu thu gom rác? Nếu có các đối tượng không thể truy cập được - những đối tượng không có liên kết hoạt động. Hãy xem một ví dụ:
public static void main(String[] args)
{
// StringBuffer object sb is not eligible for garbage collection
StringBuffer sb = new StringBuffer("Flower Brackets");
System.out.println(sb);
// StringBuffer object sb is eligible for garbage collection
sb = null;
}
Trong phương thức main tôi đã tạo một đối tượng StringBuffer và một tham chiếu đến nó. Tại thời điểm này, đối tượng StringBuffer không đủ điều kiện để thu gom rác. Bây giờ tôi sẽ đặt đối tượng StringBuffer thành "null". Đối tượng hiện đủ điều kiện để thu gom rác và trở thành đối tượng không thể truy cập được trong bộ nhớ heap. Nghĩa là, việc thu gom rác thường hoạt động trong trường hợp các đối tượng không thể truy cập được. Điều này có nghĩa là các đối tượng thường được tạo trong ngữ cảnh của một “khối if” hoặc phương thức. Do đó, các đối tượng sẽ nằm ngoài phạm vi sau khi quá trình thực thi phương thức hoàn tất và có thể bị bộ thu gom rác xử lý. Vì các tham chiếu từ đối tượng cũ đến đối tượng mới tồn tại với số lượng hạn chế, điều này có nghĩa là các đối tượng đã có mặt trong ứng dụng của bạn trong một thời gian dài thường không phải là đối tượng mới được tạo. Dưới đây là một số thuật ngữ mà chúng ta nên làm quen; một trong số đó là một vật thể sống. Nó là một đối tượng trong một ứng dụng được tham chiếu bởi một đối tượng khác trong cùng một ứng dụng. Ngoài ra còn có một đối tượng "chết". Đối tượng chết là một đối tượng không thể truy cập được, được tạo trong khi gọi phương thức và sau khi lệnh gọi phương thức hoàn tất, đối tượng sẽ thoát khỏi ngữ cảnh và chỉ nằm trong vùng nhớ heap.

Khi nào một đối tượng đủ điều kiện để thu gom rác?

Nếu một đối tượng không có bất kỳ biến tham chiếu nào thì đối tượng đó đủ điều kiện để thu gom rác.

Làm cách nào để tạo một đối tượng có sẵn để thu gom rác?

Dưới đây là một số cách:
  1. null reference variable
    Student obj = new Student();
    obj = null;

  2. re-assign reference variable
    Student obj1 = new Student();
    Student obj2 = new Student();
    obj1 = obj2;

  3. reate anonymous object
    new Student();

    Khi một đối tượng được cung cấp cho bộ thu gom rác, nó sẽ không bị phá hủy ngay lập tức.

Khi Máy ảo Java chạy trình thu gom rác, chỉ có đối tượng bị hủy. LƯU Ý: Trình thu gom rác chỉ thu thập các đối tượng được tạo bằng từ khóa “mới”, đối với các đối tượng không có từ khóa “mới”, hãy sử dụng phương thức Finalize() . Có một số phương pháp để chạy trình thu gom rác trong Máy ảo Java:
  1. Phương thức System.gc()

  2. phương thức hoàn thiện ()

  3. Phương thức Runtime.getRuntime().gc()

Phương thức gc() tĩnh nằm trong lớp Hệ thống . Phương thức này yêu cầu JVM gọi trình thu gom rác. Hãy xem cách một ứng dụng Java gọi trình thu gom rác bằng phương thức gc() .
public class GarbageCollector
{
public static void main(String[] args)
{
Employee obj1 = new Employee();
Employee obj2 = new Employee();
obj1 = null;
obj2 = null;
System.gc();
}
public void finalize()
{
System.out.println("object garbage collected");
}
}
Kết quả:
đối tượng thu gom rác đối tượng thu gom rác
Phương thức Finalize() được gọi ngay trước khi đối tượng được dọn sạch. Phương thức này được định nghĩa trong lớp Object :
protected void finalize() throws Throwable
  1. Phương thức Finalize được sử dụng để đóng kết nối tới cơ sở dữ liệu.

  2. Phương thức này được gọi bởi trình thu gom rác chứ không phải JVM.

  3. Chúng ta cần ghi đè phương thức Finalize() . Bởi vì nó có một triển khai trống.

  4. Nó chỉ được gọi một lần cho mỗi đối tượng.

Phương thức getRuntime().gc() có trong lớp thời gian chạy. Nó trả về đối tượng Runtime được liên kết với ứng dụng Java hiện tại. Chúng ta hãy xem phương pháp này trong một chương trình Java.
public class Demo
{
public static void main(String[] args)
{
Demo obj1 = new Demo();
Demo obj2 = new Demo();
// nullifying reference variable
obj1 = null;
// nullifying reference variable
obj2 = null;
// running Garbage Collector
Runtime.getRuntime().gc();
}
@Override
protected void finalize() throws Throwable
{
System.out.println("Garbage collector called");
System.out.println("Object garbage collector: " + this);
}
}
Kết quả:
Trình thu gom rác được gọi là Trình thu gom rác đối tượng: Demo@2130772 Trình thu gom rác được gọi là Trình thu gom rác đối tượng: Demo@cd4e940

Lợi ích của việc thu gom rác:

  1. Việc thu gom rác trong Java diễn ra tự động, giúp chúng ta tránh được gánh nặng bổ sung trong việc giải phóng bộ nhớ đã sử dụng. Điều này làm cho bộ nhớ của chương trình Java hiệu quả hơn.
  2. Thu gom rác đảm bảo tính toàn vẹn của chương trình.
  3. Chúng ta không cần viết thêm bất kỳ mã nào vì trình thu gom rác là một phần của JVM.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION