সি # তে বাইটে অবজেক্টের উদাহরণের আকারটি সন্ধান করুন


113

যেকোন স্বেচ্ছাচারিত উদাহরণের জন্য (বিভিন্ন অবজেক্ট, কম্পোজিশন, একক জিনিস ইত্যাদির সংগ্রহ)

আমি কীভাবে এটির আকার বাইটে নির্ধারণ করতে পারি?

(আমি বর্তমানে বিভিন্ন বস্তুর একটি সংগ্রহ পেয়েছি এবং আমি এর সামগ্রিক আকার নির্ধারণ করার চেষ্টা করছি)

সম্পাদনা: কেউ কি অবজেক্টের জন্য কোনও এক্সটেনশন পদ্ধতি লিখেছেন যা এটি করতে পারে? এটি বেশ ঝরঝরে ইমো হবে।



উত্তর:


60

প্রথমত, একটি সতর্কবাণী: যা কঠোরভাবে অনুসরণ করে তা হ'ল কুরুচিপূর্ণ, অননুমোদিত হ্যাকের রাজ্যে। এই কাজের উপর নির্ভর করবেন না - যদিও এটি এখন আপনার জন্য কাজ করে, এটি কোনও নাবালিক বা বড় .NET আপডেট সহ আগামীকাল কাজ বন্ধ করে দিতে পারে।

আপনি CLR অভ্যন্তরীণ উপর এই প্রবন্ধে তথ্য ব্যবহার করতে পারে কিভাবে CLR তৈরি করে রানটাইম বস্তুগুলি দেখতে ড্রিল মধ্যে .NET ফ্রেমওয়ার্ক internals - দুটিই MSDN ম্যাগাজিন ইস্যু 2005 মে - শেষ আমি চেক, এটা এখনও প্রযোজ্য ছিল। এটি কীভাবে করা হয় তা এখানে (এটি TypeHandleপ্রকারের মাধ্যমে অভ্যন্তরীণ "বেসিক ইনস্ট্যান্সের আকার" ক্ষেত্রটি পুনরুদ্ধার করে )।

object obj = new List<int>(); // whatever you want to get the size of
RuntimeTypeHandle th = obj.GetType().TypeHandle;
int size = *(*(int**)&th + 1);
Console.WriteLine(size);

এটি 3.5 এসপি 1 32-বিটে কাজ করে। আমি নিশ্চিত না field৪-বিটের ক্ষেত্রে ক্ষেত্রের আকারগুলি একই হয় কিনা - আপনাকে প্রকারগুলি এবং / অথবা অফসেটগুলি না থাকলে সামঞ্জস্য করতে হতে পারে।

এটি সমস্ত "সাধারণ" প্রকারের জন্য কাজ করবে, যার জন্য সমস্ত দৃষ্টান্তে একই, সু-সংজ্ঞায়িত প্রকার রয়েছে। যার জন্য এটি সত্য নয় তারা নিশ্চিতভাবে অ্যারে এবং স্ট্রিং এবং আমি এটিও বিশ্বাস করি StringBuilder। তাদের জন্য আপনি সমস্ত বিদ্যমান উপাদানগুলির আকারটি তাদের বেস উদাহরণ আকারে যুক্ত করতে পারেন।


না। এটি করার কোনও "যথাযথ" উপায় নেই, কারণ এটি ভাল আচরণের কিছু নয় N নেট অ্যাপ্লিকেশনটি প্রথমে উদ্বিগ্ন হওয়া উচিত। উপরেরগুলি সিএলআর এর নির্দিষ্ট প্রয়োগের অভ্যন্তরীণ ডেটা স্ট্রাকচারের সাথে সরাসরি মকস করে (যা সহজেই .NET এর পরবর্তী সংস্করণে পরিবর্তিত হতে পারে), উদাহরণস্বরূপ।
— পাভেল মিনায়েভ

3
এটি কি সি # বা কেবল পরিচালিত সি ++ এ কাজ করার কথা? এটি এখন পর্যন্ত সি # তে খুশি নয় যে আমি এটি চেষ্টা করেছি:Cannot take the address of, get the size of, or declare a pointer to a managed type ('System.RuntimeTypeHandle')
— মাসলো

17
এর .NET 4 সংস্করণে এমনকি অনিরাপদ কোডও লাগবে না: Marshal.ReadInt32(type.TypeHandle.Value, 4)x86 এবং x64 এর জন্য কাজ করে। আমি কেবল স্ট্রাক্ট এবং ক্লাসের ধরণের পরীক্ষা করেছি। মনে রাখবেন যে এটি মান ধরণের জন্য বাক্সযুক্ত আকার দেয়। @ পাভেল সম্ভবত আপনি আপনার উত্তর আপডেট করতে পারে।
— jnm2

2
@ sab669 ভাল, তার উদাহরণ typeদিয়ে প্রতিস্থাপন করুন obj.GetType()। আপনি কোন ফ্রেমওয়ার্ক ব্যবহার করছেন তা কেবল বিবেচিত নয়, কেবল কী সিএলআর (ভি 2 বা ভি 4 বা কোরসিএলআর)। আমি কোরএলসিআরআর এ চেষ্টা করিনি।
— jnm2

2
@ সামগল্ডবার্গ এইটিকে ম্যানুয়ালি গণনা করা এক মিলিয়ন এজ কেস নিয়ে অনেক কাজ। সাইজফ আপনাকে কোনও অবজেক্টের স্থির আকার জানায়, বস্তুর রানটাইম গ্রাফের মেমরির খরচ নয়। ভিএস2017 এর মেমরি এবং সিপিইউ প্রোফাইলিং খুব ভাল, যেমন রিসার্পার এবং অন্যান্য সরঞ্জামগুলি, এবং এটিই আমি মাপতে ব্যবহার করব।
— jnm2

20

আপনি সিরিয়ালাইজযোগ্য অবজেক্টের সাথে যদি কাজ করে থাকেন তবে আপনি বাইনারি সিরিয়ালাইজার (তবে আউটপুটটিকে বিস্মৃত করার পথে) দিয়ে সিরিয়ালকরণের ভান করে আপনি আকারটি আনুমানিকভাবে সক্ষম করতে পারবেন।

class Program
{
    static void Main(string[] args)
    {
        A parent;
        parent = new A(1, "Mike");
        parent.AddChild("Greg");
        parent.AddChild("Peter");
        parent.AddChild("Bobby");

        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf =
           new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        SerializationSizer ss = new SerializationSizer();
        bf.Serialize(ss, parent);
        Console.WriteLine("Size of serialized object is {0}", ss.Length);
    }
}

[Serializable()]
class A
{
    int id;
    string name;
    List<B> children;
    public A(int id, string name)
    {
        this.id = id;
        this.name = name;
        children = new List<B>();
    }

    public B AddChild(string name)
    {
        B newItem = new B(this, name);
        children.Add(newItem);
        return newItem;
    }
}

[Serializable()]
class B
{
    A parent;
    string name;
    public B(A parent, string name)
    {
        this.parent = parent;
        this.name = name;
    }
}

class SerializationSizer : System.IO.Stream
{
    private int totalSize;
    public override void Write(byte[] buffer, int offset, int count)
    {
        this.totalSize += count;
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanSeek
    {
        get { return false; }
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override void Flush()
    {
        // Nothing to do
    }

    public override long Length
    {
        get { return totalSize; }
    }

    public override long Position
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        throw new NotImplementedException();
    }

    public override long Seek(long offset, System.IO.SeekOrigin origin)
    {
        throw new NotImplementedException();
    }

    public override void SetLength(long value)
    {
        throw new NotImplementedException();
    }
}

6
অবশ্যই, এটি আপনাকে সর্বনিম্ন আকার পেতে পারে তবে মেমরির আকার সম্পর্কে আপনাকে কিছু বলে না।
— জন স্যান্ডার্স

লোল, উত্তরগুলি পরীক্ষা করতে ফিরে আসার আগে আমার কাছে পরবর্তী লাইটব্লব ছিল বাইনারি সিরিয়ালাইজারটি ব্যবহার করা। জন, কীভাবে এটি আপনাকে স্মৃতিতে প্রকৃত আকার দেবে না?
— জেনি

2
এটি আপনাকে সিরিয়ালাইজড আকার দেবে, যা সিরিয়ালাইজারের আকার হিসাবে হবে "সিরিয়ালাইজার" উদ্দেশ্যে। এগুলি সম্ভবত "বসার স্মৃতি" উদ্দেশ্য থেকে পৃথক। উদাহরণস্বরূপ সিরিয়ালাইজার তিনটি বাইটে ছোট ছোট পূর্ণসংখ্যা সঞ্চয় করে।
— জন স্যান্ডার্স

4
যেমনটি আমি বলেছিলাম, এটি কেবল একটি আনুমানিক। এটি নিখুঁত নয়, তবে আমি একমত নই যে এটি আপনাকে মেমরির আকার সম্পর্কে "কিছুই" বলে না। আমি বলব যে এটি আপনাকে কিছু ধারণা দিয়েছে - বৃহত্তর সিরিয়ালাইজেশনগুলি সাধারণত বড় মেমরির মাপের সাথে সংযুক্ত থাকে। নেই কিছু সম্পর্ক।
— ব্লুমোনকএমএন

আমি সম্মত - একটি নেট নেট বস্তুর গ্রাফের আকারের একটি বলপার্ক অনুমান করা দরকারী useful
— ক্রেগ শিয়েরার

8

অব্যবস্থাপনাবিহীন প্রকারের জন্য, মান মানের প্রকার, স্ট্রাক্ট:

        Marshal.SizeOf(object);

পরিচালিত অবজেক্টের জন্য আমার কাছে যতটা কাছাকাছি পৌঁছেছে তা হল প্রায় অনুমান।

        long start_mem = GC.GetTotalMemory(true);

        aclass[] array = new aclass[1000000];
        for (int n = 0; n < 1000000; n++)
            array[n] = new aclass();

        double used_mem_median = (GC.GetTotalMemory(false) - start_mem)/1000000D;

সিরিয়ালাইজেশন ব্যবহার করবেন না A একটি বাইনারি ফরম্যাটারে শিরোনাম যুক্ত হয়, যাতে আপনি নিজের ক্লাস পরিবর্তন করতে পারেন এবং একটি পুরানো সিরিয়ালযুক্ত ফাইলকে পরিবর্তিত শ্রেণিতে লোড করতে পারেন।

এছাড়াও এটি আপনাকে মেমরির আসল আকার বলবে না বা মেমরির সারিবদ্ধকরণের ক্ষেত্রে গ্রহণ করবে না।

[সম্পাদনা] BiteConverter.GetBytes (প্রোপ-মান) পুনরাবৃত্তভাবে আপনার শ্রেণীর প্রতিটি সম্পত্তি ব্যবহার করে আপনি বিষয়বস্তু বাইটে পাবেন, এটি শ্রেণীর বা রেফারেন্সের ওজন গণনা করে না তবে বাস্তবের অনেক কাছাকাছি। আমি ডেটার জন্য বাইট অ্যারে এবং পয়েন্টার কাস্টিং ব্যবহার করে মানগুলি অ্যাক্সেস করার জন্য একটি পরিচালনাহীন প্রক্সি ক্লাস ব্যবহার করার পরামর্শ দিচ্ছি যদি আকারের বিষয়টি বিবেচনা করে থাকে তবে নোট করুন যে পুরানো কম্পিউটারগুলিতে নন-প্রান্তিক মেমরিটি ধীর হয়ে থাকবে তবে মোডারন র‍্যামের বিশাল ডেটাসেটগুলি হবে যথেষ্ট দ্রুততর, র‌্যাম থেকে পড়ার জন্য আকারটি হ্রাস করার কারণে স্বাক্ষরবিহীন স্বাক্ষরের চেয়ে বড় প্রভাব পড়তে পারে।


5

এটি বর্তমান। নেট প্রয়োগের ক্ষেত্রে প্রযোজ্য না, তবে আবর্জনা সংগ্রহ / পরিচালিত রানটাইমগুলির সাথে মনে রাখার একটি বিষয় হ'ল প্রোগ্রামের আজীবন কোনও অবজেক্টের বরাদ্দ করা আকার পরিবর্তন করতে পারে। উদাহরণস্বরূপ, কিছু প্রজন্মের আবর্জনা সংগ্রহকারী (যেমন জেনারেশনাল / আল্টেরিয়র রেফারেন্স গণনা সংকর সংগ্রাহক ) কোনও জিনিস নার্সারি থেকে পরিপক্ক স্থানে স্থানান্তরিত হওয়ার পরে কেবল কিছু তথ্য সংরক্ষণ করতে হবে।

এটি অবজেক্টের আকার উন্মোচনের জন্য একটি নির্ভরযোগ্য, জেনেরিক API তৈরি করা অসম্ভব করে তোলে।


মজাদার. তাহলে লোকেরা তাদের বস্তুর আকার / অবজেক্টগুলির সংগ্রহকে গতিশীলভাবে কী করতে পারে?
— জেনি

2
এটি তাদের কীসের প্রয়োজন তা নির্ভর করে। যদি পি / ইনভোকের (নেটিভ কোড ইন্টারপ) থাকে তবে তারা মার্শাল.সাইজঅফ (টাইপফ (টি)) ব্যবহার করে। যদি মেমরি প্রোফাইলিংয়ের জন্য, তারা একটি পৃথক প্রোফাইলার ব্যবহার করে যা তথ্য সরবরাহের জন্য কার্যকরকরণ পরিবেশে সহযোগিতা করে। আপনি যদি অ্যারেতে উপাদান বিন্যাসে আগ্রহী হন তবে আপনি একটি ডায়নামিকমেডোডে সাইজঅফ আইএল অপকোড ব্যবহার করতে পারেন (আমি মনে করি না যে এটির জন্য নেট নেট ফ্রেমওয়ার্কের কোনও সহজ উপায় আছে)।
— স্যাম হারওয়েল

5

কিছু অপ্টিমাইজেশন সাইবার সেভিং / মেমরি ইউজেজ কোড সহ নিরাপদ সমাধান । কিছু ক্ষেত্রে:

/* test nullable type */      
TestSize<int?>.SizeOf(null) //-> 4 B

/* test StringBuilder */    
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) sb.Append("わたしわたしわたしわ");
TestSize<StringBuilder>.SizeOf(sb ) //-> 3132 B

/* test Simple array */    
TestSize<int[]>.SizeOf(new int[100]); //-> 400 B

/* test Empty List<int>*/    
var list = new List<int>();  
TestSize<List<int>>.SizeOf(list); //-> 205 B

/* test List<int> with 100 items*/
for (int i = 0; i < 100; i++) list.Add(i);
TestSize<List<int>>.SizeOf(list); //-> 717 B

এটি ক্লাসগুলির সাথেও কাজ করে:

class twostring
{
    public string a { get; set; }
    public string b { get; set; }
}
TestSize<twostring>.SizeOf(new twostring() { a="0123456789", b="0123456789" } //-> 28 B

এটিও আমি গ্রহণ করব। ক) অসীম পুনরাবৃত্তি এবং খ) একই স্মৃতি দু'বার যুক্ত করা এড়াতে আপনি গ্রাফটিতে আগের মুখোমুখি অবজেক্টগুলির একটি সেট যুক্ত করতে পারেন।
— মাফু

4

রানটাইমে এটি করা অসম্ভব।

যদিও বিভিন্ন মেমরি প্রোফাইলার রয়েছে যা বস্তুর আকার প্রদর্শন করে।

সম্পাদনা : আপনি একটি দ্বিতীয় প্রোগ্রাম লিখতে পারেন যা সিএলআর প্রোফাইলিং এপিআই ব্যবহার করে প্রথমটিকে প্রোফাইল করে এবং রিমোটিং বা কোনও কিছুর মাধ্যমে যোগাযোগ করে।


17
রানটাইমে এটি করা যদি অসম্ভব হয় তবে মেমরির প্রোফাইলাররা কীভাবে তথ্য সরবরাহ করছে?
— জেনি

2
প্রোফাইলিং এপিআই ব্যবহার করে। তবে, কোনও প্রোগ্রাম নিজেই প্রোফাইল করতে পারে না
— 22

মজাদার. যখন বিষয়গুলি যখন খুব বেশি স্মৃতিশক্তি গ্রহণ করে তখন আমি যদি কোডগুলি চুক্তি করতে চাইতাম?
— জেনি

4
তারপরে আপনি স্ব-সচেতন সফ্টওয়্যার নিয়ে কাজ করবেন এবং আমি খুব ভয় পাব। :-) সিরিয়াসলি, "একক দায়িত্বের অধ্যক্ষ" - প্রোগ্রামটিকে প্রোগ্রাম হতে দিন, কোডের কিছু অংশ টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো করে যা খুব বেশি স্মৃতি গ্রহণ করে।
— জন স্যান্ডার্স

2
@ জ্যানি: আপনি আকারের তাত্পর্য এবং এটি পারফরম্যান্সের সাথে কীভাবে সম্পর্কিত তা নিয়েও অনুমানগুলি তৈরি করবেন। আমি মনে করি আপনি এটি করার আগে আপনি সত্যিকারের নিম্ন-স্তরের সিএলআর পারফরম্যান্স বিশেষজ্ঞ হতে চান (যিনি ইতিমধ্যে প্রোফাইলিং এপিআই সম্পর্কে জানেন)। অন্যথায়, আপনি সম্ভবত আপনার আগের অভিজ্ঞতাগুলি এমন পরিস্থিতিতে প্রয়োগ করছেন যা তারা প্রয়োগ করে না।
— জন স্যান্ডার্স

3

সোন অফ স্ট্রাইক ব্যবহার করুন যার কমান্ড রয়েছেObjSize ।

মনে রাখবেন যে সত্যিকারের স্মৃতি গ্রাস করা ObjSizeহয়েছে এ কারণে প্রতিবেদনের চেয়ে সর্বদা বড়synkblk যা সরাসরি অবজেক্টের ডেটার সামনে থাকে।

এখানে এমএসডিএন ম্যাগাজিন ইস্যু 2005-এর উভয় সম্পর্কে আরও পড়ুন - সিএলআর রানটাইম অবজেক্টগুলি কীভাবে তৈরি করে তা দেখার জন্য .NET ফ্রেমওয়ার্ক ইন্টারনালগুলিতে ড্রিল করুন ।


2

আফাইক, আপনি বাইটগুলিতে প্রতিটি সদস্যের আকার গভীরভাবে গণনা ছাড়াই পারবেন না। তবে আবারও কি কোনও সদস্যের আকার (সংগ্রহের অভ্যন্তরের উপাদানগুলির মতো) বস্তুর আকারের সাথে বা সেই সদস্যের একটি পয়েন্টারটি বস্তুর আকারের দিকে গণনা করে? আপনি এটি কীভাবে সংজ্ঞায়িত করেন তার উপর নির্ভর করে।

আমি এই পরিস্থিতিতে আগে চলে এসেছি যেখানে আমি আমার ক্যাশে থাকা বস্তুগুলি তাদের গ্রাহিত স্মৃতির উপর ভিত্তি করে সীমাবদ্ধ করতে চেয়েছিলাম।

ঠিক আছে, যদি এটি করার কিছু কৌশল থাকে তবে আমি এটি সম্পর্কে জানতে পেরে আনন্দিত হব!


2

মান ধরণের জন্য, আপনি ব্যবহার করতে পারেন Marshal.SizeOf। অবশ্যই এটি নিয়ন্ত্রণহীন স্মৃতিতে কাঠামোটি মার্শাল করতে প্রয়োজনীয় বাইটের সংখ্যা প্রদান করে, যা সিএলআর কীভাবে ব্যবহার করে তা অগত্যা নয়।


সাইজঅফ (অবজেক্ট) ভবিষ্যতে প্রকাশে অনুপলব্ধ হতে পারে। পরিবর্তে, মাপের <T> () ব্যবহার করুন। আরও তথ্যের জন্য go.microsoft.com/fwlink/?LinkID=296514
— ভিনিগাস

1

আপনি সর্বজনীন সদস্য বা সম্পত্তির তথ্য সংগ্রহ করার জন্য প্রতিচ্ছবিটি ব্যবহার করতে পারেন (বস্তুর ধরণ দেওয়া হয়েছে)। যদিও বস্তুর উপর প্রতিটি পৃথক ডেটা দিয়ে হাঁটা ছাড়াই আকার নির্ধারণের কোনও উপায় নেই।


1

যে [Serializable]ক্লাসগুলির প্রয়োজন হয় না এবং যেখানে সঠিক বিজ্ঞানের পরিবর্তে ফলাফল একটি সন্নিবেশ হয় এমন কোনও সন্ধানের জন্য For আমি খুঁজে পেতে সবচেয়ে ভাল পদ্ধতিটি ইউটিএফ 32 এনকোডিং ব্যবহার করে মেমরিস্ট্রিমে জসন সিরিয়ালাইজেশন।

private static long? GetSizeOfObjectInBytes(object item)
{
    if (item == null) return 0;
    try
    {
        // hackish solution to get an approximation of the size
        var jsonSerializerSettings = new JsonSerializerSettings
        {
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
            DateTimeZoneHandling = DateTimeZoneHandling.Utc,
            MaxDepth = 10,
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };
        var formatter = new JsonMediaTypeFormatter { SerializerSettings = jsonSerializerSettings };
        using (var stream = new MemoryStream()) { 
            formatter.WriteToStream(item.GetType(), item, stream, Encoding.UTF32);
            return stream.Length / 4; // 32 bits per character = 4 bytes per character
        }
    }
    catch (Exception)
    {
        return null;
    }
}

না, এটি আপনাকে সঠিক আকার দেয় না যা মেমরিতে ব্যবহৃত হবে। পূর্বে উল্লিখিত হিসাবে, এটি সম্ভব নয়। তবে এটি আপনাকে একটি মোটামুটি অনুমান দেবে।

মনে রাখবেন এটিও বেশ ধীর।


1

পাভেল এবং জেএনএম 2 থেকে:

private int DumpApproximateObjectSize(object toWeight)
{
   return Marshal.ReadInt32(toWeight.GetType().TypeHandle.Value, 4);
}

সাইড নোটে সাবধান থাকুন কারণ এটি কেবল স্বচ্ছ মেমরির জিনিসগুলির সাথেই কাজ করে


1

আমি .NET: https://github.com/scholtz/TestDotNet CollectionsMemoryAllocation এ বিভিন্ন সংগ্রহের জন্য বেঞ্চমার্ক পরীক্ষা তৈরি করেছি

নীট কোর 2.2 এর জন্য ফলাফলগুলি 3 টি বৈশিষ্ট্য বরাদ্দকৃত 1,000,000 অবজেক্ট সহ নিম্নরূপ:

Testing with string: 1234567
Hashtable<TestObject>:                                     184 672 704 B
Hashtable<TestObjectRef>:                                  136 668 560 B
Dictionary<int, TestObject>:                               171 448 160 B
Dictionary<int, TestObjectRef>:                            123 445 472 B
ConcurrentDictionary<int, TestObject>:                     200 020 440 B
ConcurrentDictionary<int, TestObjectRef>:                  152 026 208 B
HashSet<TestObject>:                                       149 893 216 B
HashSet<TestObjectRef>:                                    101 894 384 B
ConcurrentBag<TestObject>:                                 112 783 256 B
ConcurrentBag<TestObjectRef>:                               64 777 632 B
Queue<TestObject>:                                         112 777 736 B
Queue<TestObjectRef>:                                       64 780 680 B
ConcurrentQueue<TestObject>:                               112 784 136 B
ConcurrentQueue<TestObjectRef>:                             64 783 536 B
ConcurrentStack<TestObject>:                               128 005 072 B
ConcurrentStack<TestObjectRef>:                             80 004 632 B

মেমরি পরীক্ষার জন্য আমি ব্যবহার করা সবচেয়ে ভাল খুঁজে পেয়েছি

GC.GetAllocatedBytesForCurrentThread()

1

স্ট্রাইক / মানগুলির অ্যারেগুলির জন্য, এর সাথে আমার বিভিন্ন ফলাফল রয়েছে:

first = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0).ToInt64();
second = Marshal.UnsafeAddrOfPinnedArrayElement(array, 1).ToInt64();
arrayElementSize = second - first;

(বড় আকারের উদাহরণ)

যেভাবেই পন্থা হউক না কেন, আপনাকে সত্যই বুঝতে হবে যে কীভাবে নেট ফলাফল ফলাফলকে সঠিকভাবে ব্যাখ্যা করতে কাজ করে। উদাহরণস্বরূপ, ফিরে আসা উপাদান আকারটি কিছু প্যাডিং সহ "সংযুক্ত" উপাদান আকার। ওভারহেড এবং এইভাবে আকারটি বিভিন্ন ধরণের ব্যবহারের উপর নির্ভর করে: জিসি হিপের উপর, স্ট্যাকের উপর, ক্ষেত্র হিসাবে, অ্যারের উপাদান হিসাবে "বক্সযুক্ত"।

(আমি জানতে চেয়েছিলাম যে জেনেরিকদের "alচ্ছিক" যুক্তি নকল করতে "ডামি" খালি স্ট্রাক্ট (কোনও ক্ষেত্র ছাড়াই) ব্যবহার করার স্মৃতি প্রভাব কী হবে; খালি স্ট্রাক্টের সাথে জড়িত বিভিন্ন বিন্যাসের সাথে পরীক্ষা করা, আমি দেখতে পাচ্ছি যে একটি ফাঁকা কাঠামো ব্যবহার করে ( কমপক্ষে) প্রতি উপাদান 1 বাইট; আমি অস্পষ্টভাবে এটি মনে রাখতে পারি কারণ। প্রতিটি ক্ষেত্রের জন্য নেটের আলাদা ঠিকানা প্রয়োজন, যা ক্ষেত্রটি সত্যিই ফাঁকা / 0-আকারের হলে কাজ করবে না)।


0

সবচেয়ে সহজ উপায়: int size = *((int*)type.TypeHandle.Value + 1)

আমি জানি এটি বাস্তবায়নের বিশদ, কিন্তু জিসি এটির উপর নির্ভর করে এবং দক্ষতার জন্য পদ্ধতি পদ্ধতি শুরু করার কাছাকাছি হওয়া দরকার এবং আরও কীভাবে জিসি কোড কমপ্লেক্স তা বিবেচনায় নেওয়া ভবিষ্যতে কীভাবে এটি পরিবর্তন করার সাহস পাবে না। প্রকৃতপক্ষে এটি .net ফ্রেমওয়ার্ক +। নেট কোর এর প্রতিটি ছোট / বড় সংস্করণের জন্য কাজ করে। (বর্তমানে ০.০-এর জন্য পরীক্ষা করতে অক্ষম)
আপনি যদি আরও নির্ভরযোগ্য উপায় চান তবে ডাইনামিক অ্যাসেমব্লিতে [StructLayout(LayoutKind.Auto)]একই ক্রমের সাথে একই একই ক্ষেত্র সহ একটি কাঠামো প্রেরণ করুন , এর আকারটি গ্রহণ করুন যাও sizeof আইএল নির্দেশ। আপনি স্ট্রাক্টের মধ্যে স্থিতিশীল পদ্ধতি নির্গত করতে চাইতে পারেন যা কেবল এই মানটি দেয়। তারপরে অবজেক্ট শিরোনামের জন্য 2 * IntPtr.Size যুক্ত করুন। এটি আপনাকে সঠিক মান দেওয়া উচিত।
তবে যদি আপনার ক্লাসটি অন্য শ্রেণীর থেকে নেওয়া হয় তবে আপনার প্রতিটি আকারের বেস শ্রেণীর আলাদাভাবে খুঁজে বের করতে হবে এবং শিরোনামের জন্য আবার তাদের + 2 * ইনপ্রেটার সাইজ যুক্ত করতে হবে। আপনি BindingFlags.DeclaredOnlyপতাকা সহ ক্ষেত্রগুলি পেয়ে এটি করতে পারেন ।
অ্যারে এবং স্ট্রিংগুলি সেই আকারটিকে তার দৈর্ঘ্য * উপাদান আকার যুক্ত করে। সামগ্রিক আকারের সামগ্রীর আকারের জন্য আপনাকে আরও পরিশীলিত সমাধান প্রয়োগ করতে হবে যা প্রতিটি ক্ষেত্র পরিদর্শন করা এবং এর সামগ্রীগুলি পরিদর্শন করা জড়িত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.