Soru .NET'te karmaşık nesnenin boyutunu belirleme yolları?


.NET'te karmaşık bir nesnenin toplam boyutunu belirlemenin yolları var mı? Bu nesne diğer nesnelerden oluşur ve diğer karmaşık nesnelere referanslar içerebilir. Bu nesne tarafından kapsanan nesnelerden bazıları POD olabilir, diğerleri olmayabilir.


17
2018-06-16 21:07


Menşei


Nesneler serileştirilebilir mi? - uncle brad
onlar might olabilir :) Belirsiz olduğum için üzgünüm, ama bu soruyu olabildiğince genel yapmaya çalışıyorum. - Polaris878
C # / NET bağlamında "POD" nedir? Bu bir C ++ terimi ... - Pavel Minaev
@Pavel, evet, POD bir C ++ terimidir ... int, string, float, double vb. İçin POD kullanıyorum ... temel olarak .NET için POD türleri ... değer türleri :) - Polaris878
Demek istediğim için en uygun CLR teriminin "blittable type" olduğuna inanıyorum - bu tüm primitif tiplerdir (nesne referansları hariçtir) ve tüm alanların kendileri için blittable türler olduğu yapılar. - Pavel Minaev


Cevaplar:


Sahip olduğunuz şey bir "karmaşık nesne" değil, bir nesne grafiğidir. Toplam boyutunu belirlemek için, bu grafikte yürümeniz gerekir - bazı kök nesnelerden başlayarak ve referans türlerinin alanlarını numaralandırmak ve değerlerini almak için Yansıma'yı kullanmak (ve elbette döngüleri kontrol etmek).

Belirli bir nesnenin boyutunu grafikte görmek için, bkz. ilgili bir soruya bu cevapama bunun tamamen başarısız bir kötülük olduğuna dikkat edin, tamamen desteklenmez, kırılabilir (ve zaten kırılabilir) ve göksel alanlarda bir toptan yavru soykırımıyla sonuçlanabilir. Yani, kesin bir değer elde etmek için “habersiz” bir yol yoktur, çünkü tanım gereği bir uygulama detayıdır - bunun için herhangi bir kullanımınız olmamalıdır. Ve hata ayıklama / profil oluşturma sırasında bir uygulamanın bellek kullanımını bulmak amacıyla, kesmek yeterince iyidir.


10
2018-06-16 21:23



Teşekkürler Pavel. Soruyu sorduğumda karmaşıklıkları anladım, birisinin zaten bunu hesaplayan bir nesne grafik geçişi yaratmış olsaydı merak ettim. - Polaris878


Basitçe söylemek gerekirse, bilmenin bir yolu yoktur. Tüm nesnelerin serileştirilebileceğini varsayarak, bunları bir binary bloğa serileştirmek için BinaryFormatter'i kullanabilir ve sonra bunun boyutunu okuyabilirsiniz. Bununla birlikte, bu bazı meta verileri içerecek ve gerçek nesne boyutunu şişirecektir (ancak makul bir tahmin olacaktır).

Değer türleri için Marshal.SizeOf()Sadece herhangi bir alt nesneyi dikkate almaz. İşaretçinin boyutu olarak herhangi bir iç referans türünü hesaplar.

Yansıma başka bir yoldur, ancak herhangi bir özel üyeyi hafızaya aldırmaz. Yani, yanılmadıkça, bunu gerçekten doğru şekilde yapmanın bir yolu yoktur.


4
2018-06-16 21:14





Zor ...

İki nesne aynı dize değişkenine işaret ediyorsa. Dize hangisinin "sahibi"? Bana öyle geliyor ki gerçek bir cevap almak için bir çöp koleksiyonunu simüle etmeniz gerekiyor. Tam olarak hafif değil.


2
2018-06-16 21:14



Dize burada iyi bir örnek değil, çünkü değişmez. - Paul Sasik
@Paul: Değişkenlik bununla ne ilgisi var? Buradaki nokta, bir nesnenin dışardan verilen bir dizgeye (ör. Bir dosya adı) referans göstermesidir. Bu dize nesneye "ait" mi, değil mi? Boyutunun bir parçası olarak sayılmalı mı, değil mi? - Pavel Minaev


vermek System.Runtime.InteropServices.Marshal.SizeOf() Bir atış.


1
2018-06-16 21:09



Marshal.SizeOf() Alt Nesnelerin büyüklüğünü dikkate alamaz. - drharris
Unutmayın ki güvenlik açısından kritik bir işlevdir, bu yüzden maalesef pek çok bağlamda çalışmaz. - Matt Greer
Nesnenin sıralı temsilinin büyüklüğünü verir, bu da aynı şey değildir. - Pavel Minaev


StackOverflow'ta başka bir yerde daha önce yanıtladı:

C # cinsinden nesne örneğinin boyutunu bulun

Güvenli olmayan kodu tanıtmanız gerekir (bunun için gerekli işaretçi işlemleri nedeniyle) - kod şuna benzer:

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

Ayrıca proje ayarlarını (Project-> Build sekmesi) "Güvenli olmayan kodlara izin ver" olarak işaretlemeyi de unutmayın.


1
2018-06-17 08:41