2012-11-24 19 views
10

Giả sử chúng ta có các lớp sau:Hầu hết các JVM có cấp phát bộ nhớ cho các phương thức không sử dụng không?

class DoubleOhSeven { 
    public static void doSomethingClassy(); 
    public static void neverDoThisClassy(); 
} 

class Dude { 
    public void doSomething(); 
    public void neverDoThis(); 
} 

public class Party { 
    public static void main(String[] args){ 
    DoubleOhSeven.doSomething(); 
    Dude guy = new Dude; 
    guy.doSomething(); 
    } 
} 

Tất nhiên, tất cả các phương pháp này sẽ được biên dịch vào tương ứng của họ .class: làm tĩnh/phương pháp dụ không sử dụng chiếm bộ nhớ vào thời gian chạy? Điều gì về các phương pháp được thừa kế hoặc không được sử dụng?

Trả lời

12

Các phương pháp chưa sử dụng vẫn ở đó chiếm bộ nhớ như là một phần của lớp/đối tượng, ngay cả khi chúng không được gọi trực tiếp.

Nếu chúng được tối ưu hóa, điều đó sẽ không thể thực hiện các cuộc gọi phản chiếu trên các phương pháp này.

Người ta có thể cho rằng tối ưu hóa có thể được tạo mà chỉ lưu trữ phương thức trong bộ nhớ và rác thu thập nội dung phương thức (sau đó sẽ được tìm nạp lại từ tệp lớp nếu cuộc gọi được thực hiện). 'không nhận thức được một máy ảo mà thực hiện điều này, và nó sẽ là khó để biện minh do những khả năng tối thiểu trong bộ nhớ và sự cân bằng tốc độ bất cứ khi nào một phương pháp được gọi.

Các phương pháp kế thừa không được sử dụng sẽ giống hệt nhau.

+0

Bạn có nghĩa là các cuộc gọi phản chiếu từ một số lớp khác? – fny

+0

@faraz Hoặc chính lớp đó - vì các cuộc gọi phương thức phản xạ, theo định nghĩa, được quyết định trong thời gian chạy và không biên dịch thời gian, trình biên dịch không có cách nào biết được phương thức phản xạ nào sẽ được gọi hoặc khi nào. – berry120

1

Các phương pháp không sử dụng làm giảm kích thước lớp học, nhưng các lớp được lưu trữ trong bộ nhớ PermGen. Bộ nhớ heap, nơi các đối tượng java thông thường được lưu trữ, không bị ảnh hưởng bởi kích thước lớp học

3

Bộ nhớ được sử dụng bởi một thể hiện của lớp Abc không phụ thuộc vào số lượng phương thức có trong Abc.

Bytecode được tạo rõ ràng sẽ tăng kích thước khi bạn thêm phương thức, cho dù chúng có làm gì hay không, nhưng điều đó sẽ chỉ ảnh hưởng đến kích thước của đối tượng lớp Abc.class, được tải chỉ một lần, bất kể có bao nhiêu trường hợp được tạo .

2

Kể từ khi lớp học được Safed trong ther PermGen cho Sun Hotspot JVM (mà sẽ thay đổi cho Java 8), bạn có thể làm một cái gì đó như thế này, chạy đầu tiên:

 

MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); 
long before = memoryMXBean.getNonHeapMemoryUsage().getUsed(); 
new Dude(); // class must not be loaded before 
System.out.println("Usage of dude is " + (memoryMXBean.getNonHeapMemoryUsage().getUsed() - before) + " bytes"); 
 

Và bạn sẽ thấy một cái gì đó như thế này: cách sử dụng của anh chàng là 6432 byte

và sau đó tạo ra một lớp Dude mà không có phương pháp không sử dụng và chạy thử nghiệm:

 

MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); 
long before = memoryMXBean.getNonHeapMemoryUsage().getUsed(); 
new DudeWithoutNeverDoThis(); // must not be loaded before 
System.out.println("Usage of dude without 'nerverDoThis' is " + (memoryMXBean.getNonHeapMemoryUsage().getUsed() - before) + " bytes"); 
 

và bạn thấy sự khác biệt (Cách sử dụng dude không có 'nerverDoThis' là 6176 bytes)

+0

Sẽ rất thú vị khi lấy lại các con số sau khi một phương thức trên lớp đã thực sự được gọi, và sau đó được gọi là 1000 lần. Việc gọi phương thức nhiều lần đã kích thích HotSpot biên dịch nó thành mã nguồn gốc, sẽ chiếm bộ nhớ. –

0

Phương pháp này có thể được biên dịch và tải lên PerGen.

Nhưng phương pháp JVM có thể là optimize sử dụng method inlining.

Ví dụ:

public class Test { 

    public void foo(){ 
     System.out.println("foo"); 
     bar(); 
    } 

    public void bar(){ 
     System.out.println("bar"); 
    } 
} 

Phương pháp này sẽ được biên dịch như thế này bởi trình biên dịch JIT:

public void foo(){ 
    System.out.println("foo"); 
    System.out.println("bar"); 
} 

Vì vậy, phương pháp rỗng sẽ không bao giờ được gọi.

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