2012-02-20 35 views
10

tôi có phương pháp JNI sau đó tạo ra một tập hợp các đối tượng Java natively, và sau đó trả lại cho Java:JNI đối tượng sáng tạo và quản lý bộ nhớ

JNIEXPORT jobject JNICALL Java_com_test_myClass_myMethod(JNIEnv * env, jclass klass) { 
    jclass arrayClass = env->FindClass("java/util/ArrayList"); 
    jmethodID initMethod = env->GetMethodID(arrayClass, "<init>", "()V"); 
    jmethodID addMethod = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z"); 
    jobject myArray = env->NewObject(arrayClass, initMethod); 

    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("Hello")); 
    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("World")); 

    return myArray; 
} 

Tôi có cần phải giải phóng các đối tượng được tạo ra trong mã nguồn gốc , hoặc nó được thực hiện tự động bởi GC? Nếu tôi làm, làm cách nào để làm điều đó, vì tôi cần trả lại nó cho Java?

+0

Tôi nghĩ rằng sẽ tùy thuộc vào mã nguồn gốc để thực hiện quản lý bộ nhớ riêng của mình. Trong trường hợp này, tôi tưởng tượng rằng bạn cần thêm một phương thức gốc khác để giải phóng (các) đối tượng được cấp phát mà bạn gọi theo cách thủ công khi bạn đã thực hiện xong chúng. Nói chung, nếu bạn đang làm việc với JNI thì tôi hy vọng bạn chuẩn bị cho một thế giới bị tổn thương. Câu trả lời này có thể giúp: http://stackoverflow.com/questions/214699/jni-memory-management-using-the-invocation-api – aroth

+3

@aroth - sai. nếu bạn phân bổ đối tượng Java trong JNI, chúng là các đối tượng Java, thuộc sở hữu của GC. – bmargulies

+0

@bmargulies - Làm cho tinh thần, nhưng những gì về trong trường hợp của mã nguồn gốc phân bổ các đối tượng/bộ nhớ không Java, ví dụ bằng cách gọi 'malloc()'? – aroth

Trả lời

11

Bạn không cần phải giải phóng các đối tượng Java được tạo trong mã gốc. Trong thực tế, bạn không thể. Bộ thu gom rác có thể giải phóng đối tượng khi không còn tham chiếu nào nữa.

Thỉnh thoảng, mã này hữu ích trong mã gốc để miễn phí tham chiếu cho các đối tượng Java. Điều này có thể làm giảm yêu cầu bộ nhớ khi mã gốc giữ, nhưng không còn cần, tham chiếu đến các đối tượng lớn hoặc một số lượng lớn các tham chiếu.

Từ: "Tham chiếu toàn cầu và địa phương" trong JNI specification.

Trong hầu hết các trường hợp, lập trình viên phải dựa vào VM để giải phóng tất cả các tham chiếu cục bộ sau khi phương thức gốc trả về. Tuy nhiên, có những lúc lập trình viên nên giải phóng một cách rõ ràng một tham chiếu cục bộ. Ví dụ: xem xét các trường hợp sau:

  • Phương pháp gốc truy cập đối tượng Java lớn, từ đó tạo tham chiếu cục bộ cho đối tượng Java. Phương thức gốc sau đó thực hiện tính toán bổ sung trước khi trở về người gọi. Tham chiếu cục bộ đối tượng Java lớn sẽ ngăn không cho đối tượng bị thu gom rác, ngay cả khi đối tượng không còn được sử dụng trong phần còn lại của phép tính.
  • Phương pháp gốc tạo ra một số lượng lớn các tham chiếu cục bộ, mặc dù không phải tất cả các tham chiếu đều được sử dụng cùng một lúc. Vì VM cần một lượng không gian nhất định để theo dõi tham chiếu cục bộ, việc tạo quá nhiều tham chiếu cục bộ có thể khiến hệ thống hết bộ nhớ. Ví dụ, một phương thức native lặp qua một mảng lớn các đối tượng, lấy các phần tử như là các tham chiếu cục bộ, và hoạt động trên một phần tử tại mỗi lần lặp. Sau mỗi lần lặp lại, lập trình viên không còn cần tham chiếu cục bộ cho phần tử mảng nữa.

chi tiết bổ sung được cung cấp Xem "Freeing References" trong Hướng dẫn JNI Programmer của.

+0

Tôi đọc hướng dẫn về Giải phóng tham chiếu, nhưng có một câu hỏi về nó: Có thể gọi phương thức trong bài viết đầu tiên của tôi một số lượng lớn các lần tạo ra một vấn đề cạn kiệt tài nguyên? Nếu có, tôi có thể giải phóng tài liệu tham khảo ở đâu, vì tôi vẫn cần phải trả lại? – nbarraille

+0

Các tham chiếu cục bộ được giải phóng tự động sau mỗi cuộc gọi. Bạn không cần phải làm điều đó một cách rõ ràng, trừ khi 1) bạn đã tạo một tham chiếu toàn cục hoặc 2) cần phải tham khảo nội bộ miễn phí trước khi cuộc gọi kết thúc, vì một lý do được mô tả trong liên kết. Tham chiếu bạn đang quay lại đang được sao chép.Cả myArray và điểm tham chiếu trả về cho cùng một đối tượng Java. Liên kết –

+0

đã chết ... – BeniBela

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