2010-06-16 31 views
17

Có cách nào để xác định tổng kích thước của một đối tượng phức tạp trong .NET không? Đối tượng này bao gồm các đối tượng khác và có thể giữ tham chiếu đến các đối tượng phức tạp khác. Một số đối tượng được đóng gói bởi đối tượng này có thể là POD, những đối tượng khác có thể không.Cách xác định kích thước của đối tượng phức tạp trong .NET?

+1

Các đối tượng có thể tuần tự hóa không? –

+0

họ MIGHT be :) Xin lỗi vì đã mơ hồ, nhưng tôi đang cố gắng làm cho câu hỏi này trở nên phổ biến nhất có thể. – Polaris878

+0

"POD" trong ngữ cảnh C#/.NET là gì? Đó là một thuật ngữ C++ ... –

Trả lời

10

Những gì bạn có không phải là "đối tượng phức tạp", đó là biểu đồ đối tượng. Để xác định kích thước của nó, bạn cần phải đi bộ đồ thị đó - bắt đầu với một số đối tượng gốc và sử dụng Reflection để liệt kê các trường tham chiếu và lấy giá trị của chúng (và kiểm tra các vòng lặp).

Để lấy kích thước của một đối tượng cụ thể trong biểu đồ, hãy xem this answer to a related question, nhưng lưu ý rằng đây là một bản hack tà ác, hoàn toàn không được hỗ trợ, có thể bị hỏng (và có thể đã bị hỏng) và có thể dẫn đến việc diệt chủng mèo con bán buôn các lĩnh vực trên trời. Điều đó nói rằng, không có cách nào "không hack" để có được một giá trị chính xác, bởi vì nó là một chi tiết thực hiện theo định nghĩa - bạn không nên sử dụng nó. Và với mục đích tìm ra cách sử dụng bộ nhớ của một ứng dụng trong quá trình gỡ rối/lược tả, bản hack là đủ tốt.

+0

Cảm ơn Pavel. Tôi hiểu sự phức tạp khi tôi hỏi câu hỏi, tôi chỉ tò mò nếu ai đó đã tạo ra một đồ thị đối tượng traversal tính toán này :) – Polaris878

1

Tặng System.Runtime.InteropServices.Marshal.SizeOf() một lần chụp.

+0

'Marshal.SizeOf()' không thể tính đến kích thước của các subobject. – drharris

+0

Hãy nhớ rằng đó là một chức năng quan trọng về bảo mật, do đó, không hoạt động trong nhiều bối cảnh. –

+1

Nó cho biết kích thước của đại diện được sắp xếp của đối tượng, điều này không hoàn toàn giống nhau. –

2

Tricky ...

Điều gì xảy ra nếu hai đối tượng trỏ đến cùng một biến chuỗi. Cái nào "sở hữu" chuỗi? Nghe có vẻ với tôi, bạn cần phải mô phỏng một bộ sưu tập rác để có được một câu trả lời thực sự. Không chính xác trọng lượng nhẹ.

+0

Chuỗi không phải là một ví dụ điển hình ở đây vì nó không thay đổi. –

+2

@Paul: sự bất biến phải làm gì với điều này? Vấn đề là một đối tượng có thể giữ một tham chiếu đến một chuỗi đã được gán cho nó từ bên ngoài (ví dụ: tên tệp). Liệu chuỗi đó "thuộc về" đối tượng hay không? Nó có nên được tính là một phần của kích thước của nó hay không? –

4

Nói một cách đơn giản, không có cách nào để biết. Giả sử tất cả các đối tượng được serializable, bạn có thể sử dụng một BinaryFormatter để serialize chúng thành một blob nhị phân, và sau đó đọc kích thước đó. Tuy nhiên, điều này sẽ bao gồm một số siêu dữ liệu và tăng kích thước đối tượng thực tế (nhưng nó sẽ là một ước tính hợp lý).

Đối với các loại giá trị, bạn sẽ sử dụng Marshal.SizeOf(), chỉ có nó không tính đến bất kỳ subobject nào. Nó sẽ tính toán bất kỳ loại tham chiếu nội bộ nào như kích thước của con trỏ tới nó.

Phản ánh là một cách khác, nhưng sẽ không hiển thị bất kỳ thành viên cá nhân nào chiếm bộ nhớ. Vì vậy, trừ khi tôi nhầm, không có cách nào để thực sự làm điều này đúng cách.

1

Trước đây đã trả lời ở những nơi khác trên StackOverflow:

Find size of object instance in bytes in c#

Bạn cần phải giới thiệu mã không an toàn (do hoạt động con trỏ cần cho việc này) - mã trông như thế này:

static unsafe int CalcSize(object obj) 
{ 
    RuntimeTypeHandle th = obj.GetType().TypeHandle; 
    int size = *(*(int**)&th + 1); 
    return size; 
} 

Cũng nên nhớ để đánh dấu cài đặt dự án (Dự án-> tab Xây dựng) thành "Cho phép mã không an toàn".

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