2015-06-08 15 views
7

Dưới đây là mã mẫu sử dụng giao diện Tương lai để thực hiện cuộc gọi không đồng bộ. Tôi cần một số làm rõ về phương thức get().Thu gom rác và các cuộc gọi không đồng bộ/Các đối tượng tương lai

Future<String> future = getAsyncString(); 
//do something ... 
String msg = ""; 
if (validation) 
    return; 
else 
    msg = future.get(); 
//do something else... 
return; 

Biến tương lai được khởi tạo trong một phương pháp, vì vậy biến sẽ sớm bị GC xóa sau khi thực hiện phương thức vì nó không còn được sử dụng nữa. Vì vậy, trong trường hợp mã vào câu lệnh if, trạng thái của JVM là gì? Làm thế nào là JVM sẽ xử lý kết quả được bao bọc trong trường hợp không có ai sẽ đọc nó trở lại? Nó có ảnh hưởng đến Thread Pool hay Executor thread không?

+3

Các biến không được xóa bởi GC. GC làm sạch các đối tượng không còn được gọi bởi bất kỳ biến nào. Lưu ý rằng một biến không phải là một đối tượng; một biến là tham chiếu * đối với một đối tượng. – Jesper

+0

vâng, mã cho thấy rằng cá thể trong tương lai sẽ chỉ được sử dụng bên trong phương thức – AntJavaDev

+0

Tại sao bạn xác thực sau 'getAsyncString()' và không phải trước đây? –

Trả lời

2

JVM sẽ xử lý kết quả được bao bọc trong trường hợp không có ai sẽ đọc lại?

Nếu không có ai (tôi có nghĩa là bất kỳ chương trình nào) sẽ đọc lại thì GC sẽ chăm sóc nó trong khi thu thập rác. Nhưng điều đó không có nghĩa là getAsyncString() sẽ không được thực hiện hoàn toàn, thay vào đó nó sẽ hoàn thành bình thường như một phương pháp bình thường hoàn thành.

+0

đây cũng là câu trả lời mà tôi muốn xác nhận, làm thế nào chúng ta có thể xác nhận nó? tôi có kiểm tra không gian mem trong thời gian chạy không? – AntJavaDev

+0

Bạn muốn xác nhận điều gì, đó là rác được thu thập hoặc quá trình thực thi hoàn tất? –

+0

không có nó sẽ được thực hiện cho chắc chắn, như phương pháp được gọi là, câu hỏi là những gì sẽ xảy ra với kết quả gói, trong trường hợp mã không bao giờ đạt đến tương lai.get()? nó sẽ tạo ra một rò rỉ bộ nhớ hay bất cứ điều gì? – AntJavaDev

10

JVM sẽ xử lý kết quả được bao bọc trong trường hợp không có ai sẽ đọc lại?

Có lẽ bạn đã nhận được đối tượng Future từ một số Executor. Để người thực thi này có thể đặt kết quả trong số Future, nó giữ tham chiếu đến Future. Nói cách khác, chỉ vì phương pháp tham chiếu cục bộ cho đối tượng biến mất khi ngăn xếp cuộc gọi được bật, không có nghĩa là đối tượng Future (nằm trên vùng heap) tự động đủ điều kiện để thu thập rác.

Cuộc gọi không đồng bộ không bị hủy hoặc bất kỳ điều gì tương tự. Người thực hiện sẽ thực hiện cuộc gọi, điền vào kết quả, và có lẽ là thả nó tham chiếu đến đối tượng Future. Tại , này sẽ khiến đối tượng trở nên không thể truy cập và đủ điều kiện để thu thập rác.

Nếu bạn chắc chắn rằng đang của bạn không giữ một tham chiếu đến đối tượng Future (tức bị rò rỉ nó ở phần // do something...) sau đó bạn có thể chắc chắn rằng đối tượng Future là (cuối cùng) được thu thập bởi các GC . (Người thi hành không có bất kỳ rò rỉ bộ nhớ tinh tế nào ở đây.)

[...] do đó biến sẽ sớm bị GC xóa.

Để chính xác, biến sẽ bị hủy khi ngăn xếp cuộc gọi xuất hiện. Điều này cuối cùng sẽ khiến đối tượng Future không thể truy cập được và đủ điều kiện thu gom rác thải. Tuy nhiên, đối tượng sẽ không bị thu gom rác ngay lập tức.

+0

vì vậy bạn đề nghị rằng sau khi thực hiện phương pháp, ngay cả khi tôi đã không gọi trong tương lai.get(), tham chiếu đến kết quả được bao bọc sẽ vẫn còn đó, như là người thực hiện thread giữ biến? – AntJavaDev

+0

Vâng, đúng vậy. – aioobe

+0

@AntJavaDev Phương pháp tương lai đang thực hiện sẽ không bị gián đoạn. Nó sẽ hoàn thành, tại thời điểm đó Executor sẽ giải phóng tham chiếu của nó và đối tượng Future sẽ đủ điều kiện cho việc thu gom rác thải. – Sinkingpoint

0

Bạn có đảm bảo rằng đối tượng sẽ không được GC trong khi bạn đang ở trong phạm vi mà tham chiếu đến nó được xác định, hoặc có tham chiếu đến đối tượng ở đâu đó trong mã.

Điều này áp dụng cho tất cả các đối tượng và tương lai không có sự khác biệt ở đây.Vì vậy, một khi phương pháp của bạn kết thúc và ngăn xếp cuộc gọi của nó sẽ bị xóa, tại một thời điểm nào đó đối tượng của bạn sẽ đủ điều kiện để thu gom rác, nhưng chắc chắn không phải trước khi tham chiếu đến nó tồn tại trên ngăn xếp cuộc gọi của phương thức.

1

Tôi đoán vậy. Tương lai được lên lịch sẽ có một số tham chiếu nội bộ từ hàng đợi threadpool cho đến khi hoàn thành tác vụ. Vì vậy, nó không thể được thu thập bởi gc trước khi nhiệm vụ hoàn tất.

Có thể có tồn tại mức trừu tượng bổ sung giữa tương lai và người thi hành và tương lai có thể được thu thập. Nhưng hãy chắc chắn rằng nếu tác vụ được gửi, nó sẽ được chạy. Không có vấn đề, là con trỏ đến tương lai được lưu hay không.

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