2013-11-21 40 views
7

Điều này trông giống như một câu hỏi ngớ ngẩn nhưng tôi thấy rất khó để có được nó đúng. Tôi đã hỏi những người khác nhau nhưng không thể có được một câu trả lời lý tưởng.Điều gì xảy ra sau khi một phương thức được gọi trong Java

Tôi muốn biết điều gì xảy ra sau khi chúng tôi gọi một phương thức bình thường trong Java (Được cung cấp trong môi trường luồng đơn).

sự hiểu biết của tôi là:

  1. Tất cả stack biến hiện nay đang poped-up và lưu trữ ở đâu (ở đâu?)
  2. Phương pháp cuộc gọi hiện tại ngừng
  3. Những lập luận của phương pháp mới gọi được đẩy vào ngăn xếp
  4. Mã phương thức chạy
  5. Sau khi phương thức chạy xong, ngăn xếp lại được làm trống và nội dung ngăn xếp cũ được khôi phục lại. (Điều gì đã xảy ra nếu hàm trả về một giá trị?).
  6. Mã tiếp tục bằng phương thức gọi.

Đây là câu trả lời rất không đầy đủ và có thể sai. Ai đó có thể cung cấp mô tả chi tiết hơn không?

Rất cám ơn.

+4

Tôi khá chắc chắn ngăn xếp không được dọn sạch, nếu không bạn sẽ không bao giờ nhận được StackOverflowException. – MightyPork

+0

Các bước (1) và (5) của bạn không xảy ra. Và có thêm một bước nữa, đó là đẩy giá trị trả về của phương thức lên ngăn xếp (trừ khi nó không có giá trị). –

+1

Đọc http://www.javaworld.com/jw-06-1997/jw-06-hood.html - tất cả đều được mô tả chi tiết. –

Trả lời

3

Không, đó thực sự là khá chính xác:

1) stack biến hiện nay vẫn còn trên stack

2) Các phương pháp hiện nay tạm dừng

3) Những lập luận của phương pháp mới gọi được đẩy lên ngăn xếp

4) Mã phương thức chạy

5) Sau khi phương thức chạy xong, chúng tôi bật ngăn xếp. Biến ngăn xếp của phương thức được gọi là không còn hợp lệ nữa - chúng không còn "tồn tại" tại thời điểm này nữa.

6) Chúng tôi chuyển giá trị trả lại (nếu có) cho người gọi

7) Mã tiếp tục bằng phương thức gọi. Tất cả các biến stack của nó vẫn còn nguyên vẹn.

==============================

PHỤ LỤC:

@Kevin -

  • Về mặt khái niệm, tôi nghĩ bạn đã hiểu đúng về nó. Tôi làm rõ một vài điểm, tôi hy vọng rằng sẽ giúp.

  • Liên kết của David Wallace rất tốt nếu bạn muốn đi sâu về cách JVM thực hiện "gọi phương thức".

  • Dưới đây là tổng quan về cách "ngăn xếp" hoạt động. Bất kỳ ngăn xếp nào, gọi bất kỳ chương trình con nào - không chỉ Java: http://en.wikipedia.org/wiki/Call_stack

  • Cuối cùng, Marko Topolnik là chính xác."Thực tế" gần như luôn luôn đủ phức tạp mà nó không cho vay chính nó với một câu trả lời đơn giản, phù hợp với mọi kích thước. Nhưng tôi chắc chắn nghĩ rằng sự hiểu biết của bạn là tốt. Ít nhất là ở cấp độ 10.000 foot.

IMHO ...

+0

những gì về việc đẩy/popping địa chỉ từ nơi nó được gọi là? – MightyPork

+0

Điều gì về nó? Có: địa chỉ được đẩy vào ngăn xếp khi hàm được gọi và xuất hiện từ ngăn xếp khi hàm trả về. – paulsm4

1

Đối với người phiên dịch, giả sử một phương pháp dụ, và tham gia một số quyền tự do nhỏ:

  1. Con trỏ đối tượng được sử dụng để tham khảo các đối tượng, và từ đó các Đối tượng lớp.
  2. Con trỏ phương thức nằm trong đối tượng Lớp. (Việc tra cứu để chuyển đổi tên phương thức thành chỉ mục phương thức được thực hiện phần lớn khi lớp được nạp, vì vậy đây chỉ là thao tác chỉ mục mảng.)
  3. Nói chung, một số "dấu" được đẩy lên chồng JVM. Điều này sẽ chứa con trỏ chỉ dẫn của người gọi, và một con trỏ tới chân ngăn xếp của người đó. (Rất nhiều cách triển khai khác nhau tại đây.)
  4. Định nghĩa của phương pháp được tham khảo để xem có bao nhiêu vars cục bộ là cần thiết. Có nhiều phần tử trống được đẩy lên ngăn xếp.
  5. Con trỏ đối tượng ("this") được lưu trữ trong var 0 cục bộ, và bất kỳ parm nào được lưu trữ trong 1,2,3 ... khi thích hợp.
  6. Điều khiển được chuyển sang phương thức được gọi.

Khi trở về, ngăn xếp được bật xuống đến điểm bắt đầu cuộc gọi, bất kỳ giá trị trả lại nào được đẩy lên ngăn xếp và điều khiển được chuyển lại cho người gọi.

Mã được biên dịch là khái niệm tương tự, chỉ sử dụng ngăn xếp "C" và mã được giải thích trong môi trường JITC sẽ sử dụng cả chồng JVM và ngăn xếp "C".

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