30/09/2018, 22:08

Lưu trữ dữ liệu bộ nhớ trong java

Các bạn chỉ giúp mình điều sau:
ví dụ mình có class:

class sinhvien {
  private int n;
  private String m;
}

thì 2 biến m và n có phải sẽ được lưu trữ trên Stack không?

Nguyen Ca viết 00:24 ngày 01/10/2018

private int n; private String m;

Do 2 biến này thuộc class sinhvien no sẽ được lưu trên heap
Nếu là primitive type và là local variable nó sẽ được lưu trên stack

Module Đk viết 00:22 ngày 01/10/2018

ừ cảm ơn nhé

Ben Nguyen viết 00:14 ngày 01/10/2018

Chào bạn. Tôi được biết rằng JVM cấp phát 2 bộ nhớ chính là Stack và Heap. Stack là được sử dụng để lưu trữ các biến local , parameter của phương thức. Heap sẽ lưu trữ các biến global và static. Theo như bạn @nguyenhuuca thì stack lưu trữ primitive type và local type thì nó cũng vừa đúng vừa sai, sai ở đây là primitive type được khai báo ở đâu?
nếu nó khai báo trong 1 phương thức nào đấy nó sẽ là biến local, nếu nó được khai báo như instance variable of class thì nó sẽ trở thành biến global và được lưu trong Heap. Một điểm bạn cần chú ý nữa là instance of class, nếu biến này được khai báo trong 1 phương thức thì nó sẽ là biến cục bộ. nhưng tham chiếu của nó là object sẽ được lưu trữ trên Heap.
Ví dụ. ClassA obj = new ClassA(); obj đây là 1 biến chứa tham chiếu đến 1 đối tượng của lớp ClassA, câu lệnh này chúng ta khai báo tỏng 1 phương thức cụ thể, vì vậy obj sẽ được lưu trên Stack và tham chiếu của nó là new ClassA() sẽ lưu trữ trên Heap. Nếu bạn cần biết thêm về cách nạp lớp và luồng 1 chương trình chạy, mình sẽ giải đáp giúp bạn.

Nguyen Ca viết 00:16 ngày 01/10/2018

Theo như bạn @nguyenhuuca thì stack lưu trữ primitive type và local type thì nó cũng vừa đúng vừa sai

Sai đâu vây chú, chỉ xem với

Nếu là primitive type và là local variable

Ben Nguyen viết 00:10 ngày 01/10/2018

Chào bạn! mình có giải thích phía dưới tại sao mình kết luận như vậy rồi nhé. Bạn có thể xem lại. Bạn nói rằng “Nếu là primitive type và là local variable nó sẽ được lưu trên stack” , primitive type nếu bạn khai báo bên trong 1 lớp như là biến instance của lớp thì sẽ được lưu trữ trên Heap. Mình vừa xem lại cậu trả lời của bạn, quả thực nó không sai trong trường hợp đó, nhưng với cách trả lời của bạn sẽ dễ gây ra hiểu lầm- tôi là 1 trường hợp.

Module Đk viết 00:24 ngày 01/10/2018

Bài viết của bạn đã giúp mình hiểu rõ hơn về cách lưu trữ biến với các kiểu dữ liệu khác như lớp. Nhưng mình vẫn thắc mắc theo một câu bạn nói nó khác với điều mình học được: theo mình biết thì static hay final và synchronize sẽ được lưu trữ trong một vùng nhớ riêng là data segment chứ không phải là lưu trên heap segment. Bạn có thể phản hồi cho mình điều này nhé? Cũng mong bạn nói thêm về cách nạp lớp và luồng 1 chương trình luôn.
Mình cũng nói thêm là khi khai báo một biến static trong class thì dù khởi tạo đối tượng bao nhiêu lần chăng nữa nó cũng sẽ không khởi tạo lại.
Ví dụ:

class Sinhvien {
 private static int m;
 public void show() {
   //dost
 }
}

public static void main(String []args) {
     Sinhvien a  = new Sinhvien();
     Sinhvien b = new Sinhvien();
     //thi bien  n chi duoc khoi tao mot lan duy nhat ngay khi chay chuong trinh.
    //nhưng mình cũng có một điều thắc mắc ở đây là: nếu như mình có hai file javaclass: a.java(có class //Sinhvien trên) và b.java(không có class Sinhvien trên) vậy thì liệu khi chạy file b.java thì 
//biến n này có được khởi tạo không với hai trường hợp là: hai file a.java và b.java cùng package và khác //package
}

Peace!!!

Ben Nguyen viết 00:17 ngày 01/10/2018

Bạn còn nhớ kiến thức là 1 chương trình sẽ có 1 hàm main() duy nhất chứ, và nó lại được khai báo với static. Đầu tiên JVM sẽ kiểm tra xem lớp nào chứa hàm main() trước, sau đó sẽ nạp lớp đó vào bộ nhớ, các thành viên static sẽ được đặt vào 1 vùng nhớ gọi là Class memory ở bên trong Heap. Tiếp theo sẽ phụ thuộc vào lớp đó có static initializer block không, nếu có ,lớp này sẽ được Stack nhập vào đầu tiên và thực thi trước hàm main(), mặc dù hàm main được nạp vào bộ nhớ Heap trước, nhưng 1 chương trình chạy phụ thuộc vào bộ nhớ Stack cái nào được đặt trước , cái đó chạy trước, nên người ta gọi Stack là vùng nhớ để thực thi chương trình, còn Heap được dùng để lưu trữ. Tiếp theo, Main bắt đầu được chạy, câu hỏi bạn là biến n có được chay không? nó sẽ phụ thuộc vào tính tuần tự của chương trình, đến khi nào chương trình sử dụng đến lớp cần dùng thì nó mới cấp phát trong bộ nhớ, và khi đó các thành phần trong lớp đó mới được khởi tạo, các lớp không được nạo đồng thời đâu bạn nhé, lớp nào chứa main() thì nạp đầu tiên, và tiếp theo…
Bạn có thể tham khảo tại đây. http://javaconceptoftheday.com/static-members-java/
Hoặc bạn tham khảo cuốn sách HeadFirst Java , sẽ giúp bạn hiểu rõ hơn, 2 tài nguyên này có ví dụ cụ thể, và hình ảnh mô tả quá trình thực thi sẽ giúp bạn hiểu rõ hơn.

Module Đk viết 00:18 ngày 01/10/2018

It’s very useful , thank you so much!

Module Đk viết 00:23 ngày 01/10/2018

Mình có tìm hiểu lại thì cảm thấy bài viết trên link bạn được có vẻ hơi sai sót. Thực sự khi mình đọc mấy bài đó mình cứ nghĩ là data segment trong heap segment nhưng xem đi xem lại và tra cứu thêm thì thấy có vẻ sai thì phải. Cũng như trong C++, java cx sẽ có vùng nhớ data segment: lưu trữ các biến static , global. Thực sự bạn có thể đính chính lại không? link mình xem: https://toithacmac.wordpress.com/2015/04/18/bai-1-ban-da-biet-cach-to-chuc-luu-tru-du-lieu-cua-mot-chuong-trinh-java-tren-bo-nho-may-tinh/

Ben Nguyen viết 00:20 ngày 01/10/2018

Bạn có thể tham khảo thêm ở đây nhé. http://www.journaldev.com/4098/java-heap-space-vs-stack-memory . Nhiều luồng ý kiến trái chiều quá , mình cũng cảm thấy bối rối. Để mình tìm đọc tài liệu của Oracle xem thế nào rồi trả lời bạn nhé.

Module Đk viết 00:20 ngày 01/10/2018

OK bạn mong phản hồi từ bạn và tự mình cũng sẽ tìm hiểu thêm.

Bài liên quan
0