জাভাতে কোনও জিনিসের আকার নির্ধারণের সেরা উপায় কী?


616

আমার কাছে একটি অ্যাপ্লিকেশন রয়েছে যা ডেটা সারিগুলির গাদা সহ একটি সিএসভি ফাইল পড়ে। আমি ব্যবহারকারীর উপাত্তের ধরণের ভিত্তিতে সারি সংখ্যার সংক্ষিপ্তসার দিয়েছি, তবে আমি নিশ্চিত করতে চাই যে আমি খুব বেশি সারি ডেটাতে না পড়ি এবং OutOfMemoryErrorএর কারণগুলি। প্রতিটি সারি একটি বস্তুতে অনুবাদ করে। প্রোগ্রামিয়্যাটিকভাবে সেই অবজেক্টটির আকার খুঁজে পাওয়ার কোনও সহজ উপায় আছে কি? একটি রেফারেন্স আছে যা সংজ্ঞা দেয় যে কত বড় আদিম ধরণের এবং অবজেক্টের রেফারেন্স হয় VM?

এই মুহুর্তে, আমার কাছে এমন কোড রয়েছে যা বলছে 32,000 সারি পর্যন্ত পড়ুন , তবে আমি এমন কোডও রাখতে চাই যা বলবে যতক্ষণ না আমি 32MB মেমরি ব্যবহার না করে যতটা সম্ভব সারি সারি পড়ি । হতে পারে এটি একটি ভিন্ন প্রশ্ন, তবে আমি এখনও জানতে চাই।


আমি mvn configs সঙ্গে আমার এজেন্ট জুড়েছে এবং ব্যাখ্যা এখানে কিভাবে: stackoverflow.com/a/36102269/711855
juanmf

উত্তর:


461

আপনি java.lang.instrument প্যাকেজটি ব্যবহার করতে পারেন

একটি ক্লাসে এই ক্লাসটি সংকলন করুন এবং রাখুন:

import java.lang.instrument.Instrumentation;

public class ObjectSizeFetcher {
    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }

    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}

আপনার সাথে নিম্নলিখিতগুলি যুক্ত করুন MANIFEST.MF:

Premain-Class: ObjectSizeFetcher

GetObjectSize ব্যবহার করুন:

public class C {
    private int x;
    private int y;

    public static void main(String [] args) {
        System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
    }
}

সাথে আহ্বান:

java -javaagent:ObjectSizeFetcherAgent.jar C

2
@ স্টেফান চমৎকার ইঙ্গিত! আপনি কি দয়া করে বলতে পারবেন, এর আকার হবে কি byte[0], byte[1], byte[5], int[0], int[1], int[2]পদ্ধতির ব্যবহার করে আপনি বর্ণনা? এটি দুর্দান্ত হবে, যদি ফলাফলগুলিতে অ্যারে এবং মেমরি সারিবদ্ধতার দৈর্ঘ্যের জন্য ওভারহেড অন্তর্ভুক্ত থাকে।
dma_k

8
আমি এটি চেষ্টা করে দেখেছি এবং আজব এবং অপ্রয়োজনীয় ফলাফল পেয়েছি। স্ট্রিংগুলি সর্বদা আকারে নির্বিশেষে 32 ছিল। আমি ভেবেছিলাম এটি সম্ভবত পয়েন্টারের আকার তবে আমার তৈরি অন্য অপরিবর্তনীয় শ্রেণীর জন্য আমি 24 পেয়েছি। এটি আদিমদের পক্ষে ভাল কাজ করে তবে তারপরে আপনার চরিত্রটি কত বড় তা আপনাকে জানাতে সত্যিই কোনও প্রোগ্রামের দরকার নেই।
ব্রেল

6
@ ব্রেল এই দ্রষ্টব্যটি ডকুমেন্টেশনে উল্লিখিত "সুনির্দিষ্ট বস্তুর দ্বারা সঞ্চয়ের পরিমাণের পরিমাণের একটি মাত্র" x এছাড়াও আমি মনে করি যে লেখকরা জাওয়ার স্ট্রিং পুলের কারণে একটি স্ট্রিংয়ের আকার 32 বাইট (কেবলমাত্র পয়েন্টার?) হিসাবে সেট করার সিদ্ধান্ত নিয়েছেন, যা স্ট্রিং উদাহরণটি ভাগ করে নেওয়া হয়েছে (পুলটিতে সঞ্চিত) বা বলা শক্ত হয়ে যায় বা স্থানীয় এবং ক্লাসে অনন্য।
আন্দ্রেই আমি

11
আমি কীভাবে অবজেক্টসাইজফ্যাচার ব্যবহার করতে পারি, যদি জারটি রফতানি না করে? আমি গ্রহণে পরীক্ষা জাভা প্রকল্প আছে।
ইউরা শিংকারেভ

3
@ ফ্রেল স্ট্রিংয়ের আসল দৈর্ঘ্য নির্বিশেষে মাত্র 32 বাইট হওয়ার কারণ হ'ল স্ট্রিংয়ের পরিবর্তনশীল দৈর্ঘ্যের অংশটি একটি চরে [] সংরক্ষণ করা হয় যা এটি তার নিজস্ব অবজেক্ট। কোনও বস্তুর প্রকৃত আকার পেতে আপনাকে নিজের আকার এবং প্রতিটি বস্তুর আকার উল্লেখ করতে হবে।
tombrown52

115

আপনার জোল , ওপেনজেডিকে প্রকল্পের অংশ হিসাবে বিকশিত একটি সরঞ্জাম ব্যবহার করা উচিত ।

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

আদিম, রেফারেন্স এবং অ্যারে উপাদানগুলির আকার পেতে, ব্যবহার করুন VMSupport.vmDetails()। ওরাকল জেডিকে 1.8.0_40 এ On৪-বিট উইন্ডোজ চলমান (নিম্নলিখিত সমস্ত উদাহরণের জন্য ব্যবহৃত), এই পদ্ধতিটি ফিরে আসে

Running 64-bit HotSpot VM.
Using compressed oop with 0-bit shift.
Using compressed klass with 3-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

আপনি ব্যবহার করে কোনও অবজেক্টের অগভীর আকার পেতে পারেন ClassLayout.parseClass(Foo.class).toPrintable()(allyচ্ছিকভাবে একটি উদাহরণটি পাস করে toPrintable)। এটি কেবলমাত্র সেই শ্রেণীর একক দৃষ্টিতে ব্যবহৃত স্থান; এটিতে এই শ্রেণীর দ্বারা উল্লিখিত অন্য কোনও অবজেক্ট অন্তর্ভুক্ত নয়। এটা তোলে নেই বস্তুর হেডারের জন্য VM- র ওভারহেড, ক্ষেত্র প্রান্তিককরণ এবং প্যাডিং অন্তর্ভুক্ত। এর জন্য java.util.regex.Pattern:

java.util.regex.Pattern object internals:
 OFFSET  SIZE        TYPE DESCRIPTION                    VALUE
      0     4             (object header)                01 00 00 00 (0000 0001 0000 0000 0000 0000 0000 0000)
      4     4             (object header)                00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000)
      8     4             (object header)                cb cf 00 20 (1100 1011 1100 1111 0000 0000 0010 0000)
     12     4         int Pattern.flags                  0
     16     4         int Pattern.capturingGroupCount    1
     20     4         int Pattern.localCount             0
     24     4         int Pattern.cursor                 48
     28     4         int Pattern.patternLength          0
     32     1     boolean Pattern.compiled               true
     33     1     boolean Pattern.hasSupplementary       false
     34     2             (alignment/padding gap)        N/A
     36     4      String Pattern.pattern                (object)
     40     4      String Pattern.normalizedPattern      (object)
     44     4        Node Pattern.root                   (object)
     48     4        Node Pattern.matchRoot              (object)
     52     4       int[] Pattern.buffer                 null
     56     4         Map Pattern.namedGroups            null
     60     4 GroupHead[] Pattern.groupNodes             null
     64     4       int[] Pattern.temp                   null
     68     4             (loss due to the next object alignment)
Instance size: 72 bytes (reported by Instrumentation API)
Space losses: 2 bytes internal + 4 bytes external = 6 bytes total

আপনি ব্যবহার করে কোনও অবজেক্টের উদাহরণের গভীর আকারের একটি সংক্ষিপ্ত চিত্র পেতে পারেন GraphLayout.parseInstance(obj).toFootprint()। অবশ্যই, পদচিহ্নের কিছু অবজেক্টগুলি ভাগ করা যেতে পারে (অন্যান্য সামগ্রী থেকেও রেফারেন্স করা হয়), সুতরাং এটি সেই জায়গার একটি ওভারপ্রসক্সিমেশন যা সেই বস্তুটি আবর্জনা সংগ্রহ করা হলে পুনরায় দাবি করতে পারে। Pattern.compile("^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$")( এই উত্তর থেকে নেওয়া ) এর ফলাফলের জন্য , জোল মোট 1840 বাইটের পায়ের ছাপ রিপোর্ট করে, যার মধ্যে কেবল 72 প্যাটার্নের উদাহরণ।

java.util.regex.Pattern instance footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1       112       112   [C
         3       272       816   [Z
         1        24        24   java.lang.String
         1        72        72   java.util.regex.Pattern
         9        24       216   java.util.regex.Pattern$1
        13        24       312   java.util.regex.Pattern$5
         1        16        16   java.util.regex.Pattern$Begin
         3        24        72   java.util.regex.Pattern$BitClass
         3        32        96   java.util.regex.Pattern$Curly
         1        24        24   java.util.regex.Pattern$Dollar
         1        16        16   java.util.regex.Pattern$LastNode
         1        16        16   java.util.regex.Pattern$Node
         2        24        48   java.util.regex.Pattern$Single
        40                1840   (total)

আপনি যদি পরিবর্তে এটি ব্যবহার করেন তবে GraphLayout.parseInstance(obj).toPrintable()জোল আপনাকে প্রতিটি রেফারেন্সযুক্ত সামগ্রীর ঠিকানা, আকার, প্রকার, মান এবং ক্ষেত্রের dereferencesগুলির পথ জানাবে, যদিও এটি সাধারণত কার্যকরভাবে খুব বেশি বিশদ হয়। চলমান প্যাটার্ন উদাহরণের জন্য, আপনি নিম্নলিখিত পেতে পারেন। (অ্যাড্রেসগুলি সম্ভবত রানের মধ্যে পরিবর্তিত হবে))

java.util.regex.Pattern object externals:
          ADDRESS       SIZE TYPE                             PATH                           VALUE
         d5e5f290         16 java.util.regex.Pattern$Node     .root.next.atom.next           (object)
         d5e5f2a0        120 (something else)                 (somewhere else)               (something else)
         d5e5f318         16 java.util.regex.Pattern$LastNode .root.next.next.next.next.next.next.next (object)
         d5e5f328      21664 (something else)                 (somewhere else)               (something else)
         d5e647c8         24 java.lang.String                 .pattern                       (object)
         d5e647e0        112 [C                               .pattern.value                 [^, [, a, -, z, A, -, Z, 0, -, 9, _, ., +, -, ], +, @, [, a, -, z, A, -, Z, 0, -, 9, -, ], +, \, ., [, a, -, z, A, -, Z, 0, -, 9, -, ., ], +, $]
         d5e64850        448 (something else)                 (somewhere else)               (something else)
         d5e64a10         72 java.util.regex.Pattern                                         (object)
         d5e64a58        416 (something else)                 (somewhere else)               (something else)
         d5e64bf8         16 java.util.regex.Pattern$Begin    .root                          (object)
         d5e64c08         24 java.util.regex.Pattern$BitClass .root.next.atom.val$rhs        (object)
         d5e64c20        272 [Z                               .root.next.atom.val$rhs.bits   [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
         d5e64d30         24 java.util.regex.Pattern$1        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e64d48         24 java.util.regex.Pattern$1        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs.val$rhs (object)
         d5e64d60         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e64d78         24 java.util.regex.Pattern$1        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$rhs (object)
         d5e64d90         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e64da8         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs.val$lhs (object)
         d5e64dc0         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs (object)
         d5e64dd8         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs        (object)
         d5e64df0         24 java.util.regex.Pattern$5        .root.next.atom                (object)
         d5e64e08         32 java.util.regex.Pattern$Curly    .root.next                     (object)
         d5e64e28         24 java.util.regex.Pattern$Single   .root.next.next                (object)
         d5e64e40         24 java.util.regex.Pattern$BitClass .root.next.next.next.atom.val$rhs (object)
         d5e64e58        272 [Z                               .root.next.next.next.atom.val$rhs.bits [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
         d5e64f68         24 java.util.regex.Pattern$1        .root.next.next.next.atom.val$lhs.val$lhs.val$lhs (object)
         d5e64f80         24 java.util.regex.Pattern$1        .root.next.next.next.atom.val$lhs.val$lhs.val$rhs (object)
         d5e64f98         24 java.util.regex.Pattern$5        .root.next.next.next.atom.val$lhs.val$lhs (object)
         d5e64fb0         24 java.util.regex.Pattern$1        .root.next.next.next.atom.val$lhs.val$rhs (object)
         d5e64fc8         24 java.util.regex.Pattern$5        .root.next.next.next.atom.val$lhs (object)
         d5e64fe0         24 java.util.regex.Pattern$5        .root.next.next.next.atom      (object)
         d5e64ff8         32 java.util.regex.Pattern$Curly    .root.next.next.next           (object)
         d5e65018         24 java.util.regex.Pattern$Single   .root.next.next.next.next      (object)
         d5e65030         24 java.util.regex.Pattern$BitClass .root.next.next.next.next.next.atom.val$rhs (object)
         d5e65048        272 [Z                               .root.next.next.next.next.next.atom.val$rhs.bits [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
         d5e65158         24 java.util.regex.Pattern$1        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e65170         24 java.util.regex.Pattern$1        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs.val$rhs (object)
         d5e65188         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs (object)
         d5e651a0         24 java.util.regex.Pattern$1        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$rhs (object)
         d5e651b8         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom.val$lhs.val$lhs (object)
         d5e651d0         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom.val$lhs (object)
         d5e651e8         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom (object)
         d5e65200         32 java.util.regex.Pattern$Curly    .root.next.next.next.next.next (object)
         d5e65220        120 (something else)                 (somewhere else)               (something else)
         d5e65298         24 java.util.regex.Pattern$Dollar   .root.next.next.next.next.next.next (object)

"(অন্য কিছু)" এন্ট্রিগুলি গাদাতে থাকা অন্যান্য বস্তুগুলিকে বর্ণনা করে যা এই বস্তুর গ্রাফের অংশ নয়

সেরা জোল ডকুমেন্টেশন হ'ল জোল সংগ্রহস্থলের জোল নমুনা । নমুনাগুলি সাধারণ জোল অপারেশনগুলি প্রদর্শন করে এবং দেখায় আপনি কীভাবে ভিএম এবং আবর্জনা সংগ্রহকারী অভ্যন্তরীণ বিশ্লেষণ করতে জোল ব্যবহার করতে পারেন।


18
এই উত্তরের আরও উপাখ্যান থাকা উচিত। অবশ্যই চেক করার জন্য একটি খুব ভাল বিকল্প। সম্পাদনা: পরীক্ষা করা হয়েছে যে এই বছরে এটি যুক্ত করা হয়েছিল এবং '08-এ প্রশ্ন জিজ্ঞাসা করা হয়েছিল। এই মুহূর্তে ওপি যা বলেছিল তা করার জন্য সম্ভবত সবচেয়ে ভাল এবং সহজ বিকল্প।
ভাড়া

4
সরঞ্জাম লেখক জোল সম্পর্কে একটি ব্লগ পোস্ট লিখেছিলেন ।
মাইক

2
অবজেক্ট "অবজেক্ট" এর আকার নির্ধারণ করতে: org.openjdk.jol.info.GraphLayout.parseInstance (Obj) .totalSize ();
শক্তিমান

নোট vmDetailsএখন যে VM.current().details()
মিহা_এক্স 64

চেক করে দেখুন GraphLayout.parseInstance(instance).toFootprint()আমি বস্তুর আকারগুলি বোঝার জন্য এটি আরও দরকারী বলে মনে করি
মুগেন

81

আমি দুর্ঘটনাক্রমে একটি java বর্গ "jdk.nashorn.intern.ir.debug.ObjectSizeCalculator" পেয়েছি, ইতিমধ্যে jdk এ, যা ব্যবহার করা সহজ এবং কোনও বস্তুর আকার নির্ধারণের জন্য বেশ কার্যকর বলে মনে হচ্ছে।

System.out.println(ObjectSizeCalculator.getObjectSize(new gnu.trove.map.hash.TObjectIntHashMap<String>(12000, 0.6f, -1)));
System.out.println(ObjectSizeCalculator.getObjectSize(new HashMap<String, Integer>(100000)));
System.out.println(ObjectSizeCalculator.getObjectSize(3));
System.out.println(ObjectSizeCalculator.getObjectSize(new int[]{1, 2, 3, 4, 5, 6, 7 }));
System.out.println(ObjectSizeCalculator.getObjectSize(new int[100]));

ফলাফল:

164192
48
16
48
416

3
এখানে একই, আমি উপরে প্রস্তাবিত অন্যান্য সমাধানগুলি চেষ্টা করছিলাম এবং অবজেক্টসাইজক্যালকুলেটরটি পেরিয়ে এসেছি। আমি বিশ্বাস করি যে এর আগে কেউ জেডকে ৮-তে ন্যাশর্ন প্রকল্পের অংশ হিসাবে সম্প্রতি চালু হওয়ার আগে কেউ উল্লেখ করেনি । তবে ওয়েবে এই ক্লাস সম্পর্কে কোনও অফিসিয়াল ডকুমেন্টেশন আমি পাইনি।
হেনরিক Gontijo

এটি স্ট্রিং দৈর্ঘ্যের বিবেচনা করে বলে মনে হচ্ছে না। এটি কি স্ট্যাকের আকারের প্রায়?
jontejj

1
আমার একটি হ্যাশম্যাপ রয়েছে, যেখানে com.carrotsearch.RamUsageEstimator ObjectSizeCalculator এর অর্ধেকটি সম্পর্কে ফিরে আসে returns কোনটি সত্য? - কোনটি বেশি স্বাচ্ছন্দ্যময়?
-17

8
দ্রষ্টব্য যে ObjectSizeCalculatorকেবল হটস্পট ভিএম-এ সমর্থিত
কেলানবুরকে

74

কিছু বছর আগে জাভাওয়াল্ডের সম্মিলিত এবং সম্ভাব্য নেস্টেড জাভা বস্তুর আকার নির্ধারণের জন্য একটি নিবন্ধ ছিল , তারা মূলত একটি আকারের () বাস্তবায়ন তৈরির মধ্য দিয়ে চলে। পদ্ধতিটি মূলত অন্যান্য কাজগুলিতে গড়ে তোলে যেখানে লোকেরা পরীক্ষামূলকভাবে আদিম এবং সাধারণ জাভা অবজেক্টগুলির আকার চিহ্নিত করে এবং সেই জ্ঞানটি এমন একটি পদ্ধতির ক্ষেত্রে প্রয়োগ করে যা মোট আকারের জন্য পুনরাবৃত্তভাবে কোনও অবজেক্টের গ্রাফকে হাঁটতে পারে।

এটি সর্বদা নেটিভ সি প্রয়োগের তুলনায় কিছুটা কম নির্ভুল হতে চলেছে কেবল কোনও শ্রেণীর পর্দার আড়ালে থাকা জিনিসগুলির কারণে তবে এটি একটি ভাল সূচক হওয়া উচিত।

বিকল্পভাবে উত্সফরজ প্রকল্পটি যথাযথ আকারের নামে পরিচিত উত্সফরজ যা একটি আকারের () বাস্তবায়ন সহ একটি জাভা 5 লাইব্রেরি সরবরাহ করে।

পিএস সিরিয়ালাইজেশন পদ্ধতির ব্যবহার করবেন না, সিরিয়ালযুক্ত বস্তুর আকার এবং লাইভের সময় এটি যে পরিমাণ স্মৃতি গ্রহণ করে তার মধ্যে কোনও সম্পর্ক নেই।


6
আকারের ইউটিলিটি সম্ভবত সবচেয়ে দ্রুততম উপায়। এটি মূলত স্টিফান যা বলেছিল তা কিন্তু ব্যবহারের জন্য প্রস্তুত একটি জারে ইতিমধ্যে প্যাক করা।
আলেকজান্দ্রি এল টেলস

62

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

সুতরাং একমাত্র সঠিক উপায় হল জেভিএমকে জিজ্ঞাসা করা, একটি ভাল প্রোফাইলার সহ (আমি আপনারকিট ব্যবহার করি ), যা সম্ভবত আপনি চান না।

তবে উপরের বিবরণ থেকে মনে হচ্ছে প্রতিটি সারিটি স্ব-অন্তর্ভুক্ত থাকবে এবং এতে কোনও বড় নির্ভরতা গাছ থাকবে না, তাই বেশিরভাগ জেভিএম-তে সম্ভবত সিরিয়ালাইজেশন পদ্ধতিটি খুব ভাল অনুমান হবে be এটি করার সবচেয়ে সহজ উপায়টি হ'ল:

 Serializable ser;
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 ObjectOutputStream oos = new ObjectOutputStream(baos);
 oos.writeObject(ser);
 oos.close();
 return baos.size();

মনে রাখবেন আপনার যদি সাধারণ রেফারেন্স সহ অবজেক্ট থাকে তবে এটি সঠিক ফলাফল দেয় না এবং সিরিয়ালাইজেশন আকার সর্বদা মেমরির আকারের সাথে মেলে না তবে এটি একটি ভাল আনুমানিক। আপনি বাইটআর্যআউটপুট স্ট্রিম আকারটি বোধগম্য মানতে শুরু করলে কোডটি আরও কিছুটা কার্যকর হবে।


2
আমি এই পদ্ধতির পছন্দ। বস্তুর আকারের দিক থেকে আপনি কতটা দূরে রয়েছেন।
বার্লিন ব্রাউন

1
খুব সহজ এবং কার্যকর। অন্যান্য পদ্ধতিগুলি খুব অগোছালো (বিশেষত Eclipse RCP এর অভ্যন্তরে)। ধন্যবাদ।
মার্কোলপস

19
সিরিয়ালাইজেশন ক্ষণস্থায়ী ভেরিয়েবলগুলির উপর নজর রাখে না এবং ডিফল্ট সিরিয়ালাইজেশন পদ্ধতিটি ইউটিএফ -8 এ স্ট্রিং লিখতে থাকে, সুতরাং যে কোনও এএনএসআই অক্ষর কেবল একটি বাইট নেয়। আপনার যদি অনেকগুলি স্ট্রিং থাকে তবে আপনার আকারটি অপ্রয়োজনীয় হিসাবে এতটা দূরে থাকবে।
টিএমএন

1
যদিও এটি সঠিক আকারটি দিতে পারে না, আমার প্রয়োজনের জন্য আমার কেবলমাত্র 2 টি অবজেক্ট এবং সাইজঅফের মধ্যে একটি তুলনা প্রয়োজন যা কোনও ওয়েব অ্যাপ্লিকেশন থেকে আরম্ভ হবে না। ধন্যবাদ!
আইজাক

1
আপনার কুইকের ভাল সুপারিশ । অন্যান্য বিকল্পগুলি হ'ল ভার্চুয়ালভিএম এবং জেভমনিটর
অ্যাঞ্জেলসারভেরা

38

আপনি যদি আপনার জেভিএম-তে কতটা মেমরি ব্যবহার করছেন এবং কতটা নিখরচায় তা জানতে চান আপনি এই জাতীয় কিছু চেষ্টা করতে পারেন:

// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory();

// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();

// Get amount of free memory within the heap in bytes. This size will increase
// after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();

সম্পাদনা: আমি ভেবেছিলাম এটি সহায়ক হতে পারে কারণ প্রশ্ন লেখক আরও বলেছিলেন যে তিনি যুক্তি রাখতে চান যে "যতক্ষণ না সারি সারি সারি পড়তে পারা যায় যতক্ষণ না আমি 32MB মেমরি ব্যবহার করি।"


24
এটি কোনও ভাল সমাধান নয়, কারণ কোনও জঞ্জাল সংগ্রহ কখন ঘটবে তা আপনি কখনই জানেন না বা একবারে কীভাবে অতিরিক্ত মেমরি বরাদ্দ হবে।
নিক ফরেটসিকিউ

5
এটি সত্য, এবং আমি এই পোস্টের মূল প্রশ্নটির সমাধান করার জন্য এটি করতে চাইছি না, তবে যখন তিনি সর্বোচ্চ স্তরের আকারটি আঘাতের কাছাকাছি চলে আসছেন তখন প্রোগ্রামিয়ালি বুঝতে এটি সহায়তা করতে পারে।
ম্যাট বি

1
এই সমাধানটির অন্যান্য সমস্যা হ'ল আপনি যখন বহু-থ্রেড পরিবেশে (ওয়েব সার্ভারের মতো) থাকেন। এটি সম্ভব যে অন্যান্য থ্রেডগুলি কার্যকর ছিল এবং মেমরি গ্রাস করে। এই অনুমানের সাহায্যে আপনি সমস্ত ভার্চুয়াল মেশিনে ব্যবহৃত মেমরি গণনা করছেন।
অ্যাঞ্জেলসারভেরা

1
আর একটি অসুবিধা হ'ল ফ্রিমেমরি একটি আনুমানিক প্রত্যাবর্তন করে। Javax.crypto.Cipher অবজেক্ট তৈরি করার চেষ্টা করুন। ফ্রি মেমোরিতে (একটি সাইফারের আকার অনুমান করার জন্য) দুটি কলের মধ্যে পার্থক্য স্থির নয়!
ইউজেন

1
আমি বিশ্বাস করি আপনি কোনও জঞ্জাল সংগ্রহ করতে বাধ্য করতে পারেন, সুতরাং আপনি এই পদ্ধতির কিছু জিনিস করতে পারেন
ম্যাটানস্টার

24

আমি যখন টুইটারে কাজ করেছি, আমি গভীর বস্তুর আকার গণনা করার জন্য একটি ইউটিলিটি লিখেছিলাম। এটি অ্যাকাউন্টে বিভিন্ন মেমরি মডেল গ্রহণ করে (32-বিট, সংক্ষেপিত ওফস, 64-বিট), প্যাডিং, সাবক্লাস প্যাডিং, বিজ্ঞপ্তি ডেটা স্ট্রাকচার এবং অ্যারেগুলিতে সঠিকভাবে কাজ করে। আপনি কেবল এই একটি জাভা ফাইলটি সংকলন করতে পারেন; এর কোনও বাহ্যিক নির্ভরতা নেই:

https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/objectsize/ObjectSizeCalculator.java


1
Szia! আমি আপনার উপস্থাপনাটিও চেঁচিয়ে বলতে চাই : বিভিন্ন ডেটা-স্ট্রাকচার সিদ্ধান্তের ব্যয়ের জন্য একটি স্বভাবসুলভ অনুভূতি পেতে 15-15 স্লাইডগুলি দুর্দান্ত। পোস্ট করার জন্য ধন্যবাদ!
লুক উশরউড

16
"এর কোনও বাহ্যিক নির্ভরতা নেই" - যেহেতু পেয়ারা বাহ্যিক নির্ভরতা নয়?
l4mpi


গুয়াভ একটি বাহ্যিক নির্ভরতা।
Mert Serimer

18

অন্যান্য উত্তরগুলির বেশিরভাগ অগভীর আকার সরবরাহ করে - যেমন কোনও কী বা মান ব্যতীত একটি হ্যাশম্যাপের আকার, যা আপনি চান তা সম্ভবত নয়।

জ্যাম প্রকল্পটি উপরে java.lang.instrumentation প্যাকেজটি ব্যবহার করে তবে গাছটি হাঁটে এবং তাই আপনাকে গভীর স্মৃতি ব্যবহার করতে পারে।

new MemoryMeter().measureDeep(myHashMap);

https://github.com/jbellis/jamm

মেমোরি মিটার ব্যবহার করতে, "-জাভাজন্ট: / জ্যামম.জার" দিয়ে জেভিএম শুরু করুন


11

প্রতিবিম্ব ব্যবহার করে আপনাকে অবজেক্টগুলি হাঁটতে হবে। আপনি যেমন যত্নবান হন:

  • স্রেফ কোনও বস্তু বরাদ্দ করার জেভিএম-তে কিছু ওভারহেড রয়েছে। পরিমাণটি JVM দ্বারা পরিবর্তিত হয় তাই আপনি এই মানটিকে পরামিতি করতে পারেন। কমপক্ষে এটিকে একটি ধ্রুবক তৈরি করুন (8 বাইট?) এবং বরাদ্দ যেকোন কিছুতে প্রয়োগ করুন।
  • কেবল byteতাত্ত্বিকভাবে 1 বাইট হওয়ার অর্থ এটি মেমরির ক্ষেত্রে কেবল একটি নেয়।
  • অবজেক্টের রেফারেন্সগুলিতে লুপ থাকবে, সুতরাং আপনাকে অসীম লুপগুলি অপসারণ করতে তুলনাকার হিসাবে অবজেক্ট-HashMap ইক্যুয়াল ব্যবহার করে একটি বা কিছু কিছু রাখা দরকার ।

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


জাভা স্পেসিফিকেশনে বিভিন্ন আদিম আকারগুলির সংজ্ঞা দেওয়া হয়নি? (§2.4.1)
এরিকসন

4
"এটি কতটুকু স্মৃতি ধারণ করে" এই অর্থে নয় যা প্রশ্ন। তারা কীভাবে পরিচালনা করে তা কেবল এই অর্থে। উদাহরণস্বরূপ, বাইটস, চর এবং শর্টসগুলি জাভা স্ট্যাকের উপরে পুরো শব্দটি গ্রহণ করে, যদিও তারা রাউন্ডিং ইত্যাদি দিয়ে কাজ করে operate
জেসন কোহেন

1
এটি আকার পরিমাপ করার মতোই বলে মনে হচ্ছে, যেমন হেইঞ্জ তার নিউজলেটার # 78 তে দেখিয়েছেন: javasp विशेषज्ञists.eu/archive/Issue078.html । আমি এটি ব্যবহার করেছি। তার পদ্ধতির কাজ করে।
পিটার কফলার

8

আপনাকে এটি একটি সরঞ্জাম দিয়ে পরিমাপ করতে হবে, বা হাতে এটি অনুমান করতে হবে এবং এটি আপনি যে JVM ব্যবহার করছেন তার উপর নির্ভর করে।

প্রতি বস্তুটিতে কিছু স্থির ওভারহেড রয়েছে। এটি জেভিএম-নির্দিষ্ট, তবে আমি সাধারণত 40 বাইট অনুমান করি। তারপরে আপনাকে ক্লাসের সদস্যদের দিকে নজর দিতে হবে। অবজেক্টের রেফারেন্সগুলি 32 (বিট) (64-বিট) জেভিএম-এ 4 (8) বাইট। আদিম ধরনের:

  • বুলিয়ান এবং বাইট: 1 বাইট
  • চর এবং সংক্ষিপ্ত: 2 বাইট
  • int এবং ভাসা: 4 বাইট
  • দীর্ঘ এবং ডাবল: 8 বাইট

অ্যারে একই নিয়ম অনুসরণ করে; এটি হ'ল এটি একটি অবজেক্ট রেফারেন্স যাতে আপনার অবজেক্টে 4 (বা 8) বাইট নেয় এবং তার দৈর্ঘ্যটি তার উপাদানটির আকার দিয়ে বহুগুণ হয়।

Runtime.freeMemory()জঞ্জাল সংগ্রহকারীকে অ্যাসিঙ্ক্রোনাস কল ইত্যাদির কারণে কেবলমাত্র কল করার জন্য প্রোগ্রামের মাধ্যমে এটি করার চেষ্টা করা -xrunhprof বা অন্যান্য সরঞ্জামের সাহায্যে গাদা রচনা আপনাকে সুনির্দিষ্ট ফলাফল দেয়।


@erickson আমি নিশ্চিত যাও sizeof (বুলিয়ান) == 1 এই থ্রেড (এ খুঁজছেন সম্পর্কে হবে না stackoverflow.com/questions/1907318/... )। আপনি এই সম্পর্কে মন্তব্য করতে পারেন?
dma_k

2
@ ডিএমএ_কে, জাভাতে আসলে আসল বুলেট নেই। বুলিয়ান এর আকার 4 বাইট অ্যারের বাইরে এবং 1 বেটের মধ্যে রয়েছে boolean[]। আসলে সমস্ত আদিমগুলি নন ডাবল / লং টাইপগুলি 4 বাইট। দ্বিতীয়টি 8 টি (উত্তরটি তাদের ভুল হিসাবে 4 হিসাবে রাখে)
25:48

@ বেস্টেস: আরও নির্ভুল হতে, ন্যূনতম মেমরির বরাদ্দ জেভিএমের প্ল্যাটফর্ম এবং বাস্তবায়নের উপর নির্ভর করে। এছাড়াও স্তূপে থাকা বস্তুগুলি সারিবদ্ধ হয়, সুতরাং সমস্ত মাপের সমষ্টি করার পরে একটিকে গোল করে ফেলা দরকার।
dma_k

6

java.lang.instrument.Instrumentationবর্গ একটি জাভা বস্তুর আকার পেতে একটি সুন্দর ভাবে প্রদান করে, কিন্তু এটি একটি সংজ্ঞায়িত করতে হবেpremain এবং একটি জাভা এজেন্ট সঙ্গে আপনার প্রোগ্রাম চালানো। এটি খুব বিরক্তিকর যখন আপনার কোনও এজেন্টের প্রয়োজন হয় না এবং তারপরে আপনাকে আপনার আবেদনে একটি ডামি জার এজেন্ট সরবরাহ করতে হবে।

সুতরাং আমি Unsafeক্লাসটি ব্যবহার করে একটি বিকল্প সমাধান পেয়েছি sun.misc। সুতরাং, প্রসেসরের আর্কিটেকচার অনুযায়ী অবজেক্টস হ্যাপ অ্যালাইনমেন্ট বিবেচনা করে এবং সর্বাধিক ফিল্ড অফসেট গণনা করে আপনি জাভা অবজেক্টের আকার মাপতে পারেন। নীচের উদাহরণে আমি অবজেক্টের UtilUnsafeরেফারেন্স পেতে একটি সহায়ক ক্লাস ব্যবহার করি sun.misc.Unsafe

private static final int NR_BITS = Integer.valueOf(System.getProperty("sun.arch.data.model"));
private static final int BYTE = 8;
private static final int WORD = NR_BITS/BYTE;
private static final int MIN_SIZE = 16; 

public static int sizeOf(Class src){
    //
    // Get the instance fields of src class
    // 
    List<Field> instanceFields = new LinkedList<Field>();
    do{
        if(src == Object.class) return MIN_SIZE;
        for (Field f : src.getDeclaredFields()) {
            if((f.getModifiers() & Modifier.STATIC) == 0){
                instanceFields.add(f);
            }
        }
        src = src.getSuperclass();
    }while(instanceFields.isEmpty());
    //
    // Get the field with the maximum offset
    //  
    long maxOffset = 0;
    for (Field f : instanceFields) {
        long offset = UtilUnsafe.UNSAFE.objectFieldOffset(f);
        if(offset > maxOffset) maxOffset = offset; 
    }
    return  (((int)maxOffset/WORD) + 1)*WORD; 
}
class UtilUnsafe {
    public static final sun.misc.Unsafe UNSAFE;

    static {
        Object theUnsafe = null;
        Exception exception = null;
        try {
            Class<?> uc = Class.forName("sun.misc.Unsafe");
            Field f = uc.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            theUnsafe = f.get(uc);
        } catch (Exception e) { exception = e; }
        UNSAFE = (sun.misc.Unsafe) theUnsafe;
        if (UNSAFE == null) throw new Error("Could not obtain access to sun.misc.Unsafe", exception);
    }
    private UtilUnsafe() { }
}

আকর্ষণীয় পদ্ধতির, তবে এটি কি মনে করে না যে এই অবজেক্টটি এবং এর ক্ষেত্রগুলির সঞ্চয়স্থান খণ্ডিত নয়?
নিকুলাজ

হ্যাঁ এবং আমি এমন কোনও জেভিএম বাস্তবায়ন জানি না যা এই জাতীয় খণ্ডন করে।
মিগুয়েল গ্যাম্বোয়া

আমি বুঝতে পারছি না। টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টানা একটি বিকল্প নয় :) আসুন বস্তুর সি এর উদাহরণ গ্রহণ করা যাক যা বস্তু এ এবং বি এর ক্ষেত্র হিসাবে সঞ্চিত আছে এটি পুরোপুরি A বা B এর মধ্যে স্থানান্তরিত করে না?
নিকুলাজ

দুঃখিত, তবে আমি আপনার দৃষ্টিকোণটি বুঝতে পারছি না। আমার ব্যাখ্যা অনুসারে, জাভা অবজেক্টগুলিতে অন্যান্য অবজেক্টের মধ্যে সংরক্ষণ করা যাবে না, যেমন সি স্ট্রাকচার বা। নেট এ মান ধরণের সাথে ঘটে। সুতরাং আপনি যখন বলবেন: "অবজেক্ট সি যা অবজেক্টস এ এবং বি এর ক্ষেত্র হিসাবে সঞ্চিত আছে" যার অর্থ হ'ল এ এবং বি-তে এমন ক্ষেত্র রয়েছে যা বস্তুর সি'র রেফারেন্স (পয়েন্টার) সংরক্ষণ করে তারপরে এ এবং বি এর আকার সমান হয় field ক্ষেত্রের অফসেট প্লাসের সাথে একটি রেফারেন্সের আকার (পয়েন্টার) সি। এবং রেফারেন্সের আকারটি একটি শব্দের আকার।
মিগুয়েল গ্যাম্বোয়া

ওহ, ঠিক আছে, আমরা অগভীর আকারের বিষয়ে কথা বলছি। আমার খারাপ।
নিকুলাজ

6

এছাড়াও মেমোরি মেজারার সরঞ্জাম রয়েছে (পূর্বে গুগল কোডে , এখন গিটহাবে ), যা সহজ-সরল এবং বাণিজ্যিক বান্ধব অ্যাপাচি ২.০ লাইসেন্সের আওতায় প্রকাশিত হয়েছে, যেমন একটি অনুরূপ প্রশ্নে আলোচনা করা হয়েছে ।

এটির জন্যও জাভা ইন্টারপ্রেটারের কাছে একটি কমান্ড-লাইন যুক্তি প্রয়োজন যদি আপনি মেমরি বাইট খরচ পরিমাপ করতে চান তবে অন্যথায় মনে হয় এটি ঠিক কাজ করেছে, কমপক্ষে আমি যে পরিস্থিতিতে এটি ব্যবহার করেছি in


4

ইন্সট্রুমেন্টেশন ইত্যাদির সাথে ঝামেলা না করে এবং যদি আপনাকে কোনও জিনিসের বাইট-সঠিক আকারের প্রয়োজন না জানা থাকে তবে আপনি নিম্নলিখিত পদ্ধতির সাথে যেতে পারেন:

System.gc();
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

do your job here

System.gc();
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

আপনি আগে এবং পরে ব্যবহৃত মেমরিটি এভাবে পড়েন এবং ব্যবহৃত মেমরি পাওয়ার ঠিক আগে জিসিকে কল করে আপনি "গোলমাল "টি প্রায় 0 এ নামান।

আরও নির্ভরযোগ্য ফলাফলের জন্য আপনি নিজের কাজটি এন বার চালাতে পারবেন এবং তারপরে ব্যবহৃত রেকর্ডটিকে এন দ্বারা ভাগ করতে পারেন, এক রান কত মেমরি নেয় তা অর্জন করে। আরও বেশি, আপনি পুরো জিনিসটি আরও বার চালাতে এবং গড় করতে পারেন।


5
আপনি System.gc()কেবল জিসি করতে চান তা কি জানায় না ? জিসিকে মোটেই ডেকে আনা হয়েছে তা গ্যারান্টিযুক্ত নয়।
রেলডেক্স

@সত্যিই সুন্দর. এটি নিরাপদ নয় কারণ আপনি কখনই জিসি আপনার লাইনের মধ্যে স্মৃতিকে প্রভাবিত করেন না বা প্রভাবিত করতে পারেন না। সুতরাং "দুটি" ফ্রি-মেমোরি পদ্ধতির মধ্যে "জিসি আরও বেশি জায়গা খালি করতে পারে যা আপনি বিবেচনা করেন না এভাবে আপনার অবজেক্টটি আরও ছোট দেখাবে
Mert Serimer

@ মার্টসারিমার "নিরাপদ নয়" আমার জন্য সম্পূর্ণ ভিন্ন স্তরে রয়েছে: বেশিরভাগ ক্ষেত্রে এটি এতটা সঠিক নয়, যেমনটি আমি বলেছি। এছাড়াও, আপনি জিসি চালনা করতে পারবেন না (যেমন রেলডেক্স বলেছেন), তবে এই ক্ষেত্রেও আমি এটি একটি চক্রের মধ্যে সন্নিবেশ করার পরামর্শ দিয়েছিলাম। এটি কেবল একটি দ্রুত এবং নোংরা এবং আনুমানিক সিস্টেম যা ফলাফল যদি খুব নির্ভরযোগ্য হওয়ার প্রয়োজন না হয় তবে কাজ করে।
সত্যই চমৎকার

এটির সাথে অনেকগুলি সমস্যা রয়েছে তবে এটি আপনাকে একটি ভাল সোয়াগ দেয়।
মার্কথেগ্রিয়া

3

সংযুক্ত ওওপি সহ 32-বিট, 64-বিট এবং 64-বিট হ্যান্ডেল করার জন্য আমি সংযুক্ত কয়েকটি উদাহরণ ব্যবহার করে তৈরি করেছি এমন একটি ইউটিলিটি। এটি ব্যবহার করে sun.misc.Unsafe

এটি Unsafe.addressSize()একটি স্থানীয় পয়েন্টারের Unsafe.arrayIndexScale( Object[].class )আকার এবং জাভা রেফারেন্সের আকারের জন্য ব্যবহার করে।

এটি কোনও শ্রেণীর অবজেক্টের ক্ষেত্রের অফসেট ব্যবহার করে কোনও অবজেক্টের বেজ সাইজটি ব্যবহার করে।

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Stack;
import sun.misc.Unsafe;

/** Usage: 
 * MemoryUtil.sizeOf( object )
 * MemoryUtil.deepSizeOf( object )
 * MemoryUtil.ADDRESS_MODE
 */
public class MemoryUtil
{
    private MemoryUtil()
    {
    }

    public static enum AddressMode
    {
        /** Unknown address mode. Size calculations may be unreliable. */
        UNKNOWN,
        /** 32-bit address mode using 32-bit references. */
        MEM_32BIT,
        /** 64-bit address mode using 64-bit references. */
        MEM_64BIT,
        /** 64-bit address mode using 32-bit compressed references. */
        MEM_64BIT_COMPRESSED_OOPS
    }

    /** The detected runtime address mode. */
    public static final AddressMode ADDRESS_MODE;

    private static final Unsafe UNSAFE;

    private static final long ADDRESS_SIZE; // The size in bytes of a native pointer: 4 for 32 bit, 8 for 64 bit
    private static final long REFERENCE_SIZE; // The size of a Java reference: 4 for 32 bit, 4 for 64 bit compressed oops, 8 for 64 bit
    private static final long OBJECT_BASE_SIZE; // The minimum size of an Object: 8 for 32 bit, 12 for 64 bit compressed oops, 16 for 64 bit
    private static final long OBJECT_ALIGNMENT = 8;

    /** Use the offset of a known field to determine the minimum size of an object. */
    private static final Object HELPER_OBJECT = new Object() { byte b; };


    static
    {
        try
        {
            // Use reflection to get a reference to the 'Unsafe' object.
            Field f = Unsafe.class.getDeclaredField( "theUnsafe" );
            f.setAccessible( true );
            UNSAFE = (Unsafe) f.get( null );

            OBJECT_BASE_SIZE = UNSAFE.objectFieldOffset( HELPER_OBJECT.getClass().getDeclaredField( "b" ) );

            ADDRESS_SIZE = UNSAFE.addressSize();
            REFERENCE_SIZE = UNSAFE.arrayIndexScale( Object[].class );

            if( ADDRESS_SIZE == 4 )
            {
                ADDRESS_MODE = AddressMode.MEM_32BIT;
            }
            else if( ADDRESS_SIZE == 8 && REFERENCE_SIZE == 8 )
            {
                ADDRESS_MODE = AddressMode.MEM_64BIT;
            }
            else if( ADDRESS_SIZE == 8 && REFERENCE_SIZE == 4 )
            {
                ADDRESS_MODE = AddressMode.MEM_64BIT_COMPRESSED_OOPS;
            }
            else
            {
                ADDRESS_MODE = AddressMode.UNKNOWN;
            }
        }
        catch( Exception e )
        {
            throw new Error( e );
        }
    }


    /** Return the size of the object excluding any referenced objects. */
    public static long shallowSizeOf( final Object object )
    {
        Class<?> objectClass = object.getClass();
        if( objectClass.isArray() )
        {
            // Array size is base offset + length * element size
            long size = UNSAFE.arrayBaseOffset( objectClass )
                    + UNSAFE.arrayIndexScale( objectClass ) * Array.getLength( object );
            return padSize( size );
        }
        else
        {
            // Object size is the largest field offset padded out to 8 bytes
            long size = OBJECT_BASE_SIZE;
            do
            {
                for( Field field : objectClass.getDeclaredFields() )
                {
                    if( (field.getModifiers() & Modifier.STATIC) == 0 )
                    {
                        long offset = UNSAFE.objectFieldOffset( field );
                        if( offset >= size )
                        {
                            size = offset + 1; // Field size is between 1 and PAD_SIZE bytes. Padding will round up to padding size.
                        }
                    }
                }
                objectClass = objectClass.getSuperclass();
            }
            while( objectClass != null );

            return padSize( size );
        }
    }


    private static final long padSize( final long size )
    {
        return (size + (OBJECT_ALIGNMENT - 1)) & ~(OBJECT_ALIGNMENT - 1);
    }


    /** Return the size of the object including any referenced objects. */
    public static long deepSizeOf( final Object object )
    {
        IdentityHashMap<Object,Object> visited = new IdentityHashMap<Object,Object>();
        Stack<Object> stack = new Stack<Object>();
        if( object != null ) stack.push( object );

        long size = 0;
        while( !stack.isEmpty() )
        {
            size += internalSizeOf( stack.pop(), stack, visited );
        }
        return size;
    }


    private static long internalSizeOf( final Object object, final Stack<Object> stack, final IdentityHashMap<Object,Object> visited )
    {
        // Scan for object references and add to stack
        Class<?> c = object.getClass();
        if( c.isArray() && !c.getComponentType().isPrimitive() )
        {
            // Add unseen array elements to stack
            for( int i = Array.getLength( object ) - 1; i >= 0; i-- )
            {
                Object val = Array.get( object, i );
                if( val != null && visited.put( val, val ) == null )
                {
                    stack.add( val );
                }
            }
        }
        else
        {
            // Add unseen object references to the stack
            for( ; c != null; c = c.getSuperclass() )
            {
                for( Field field : c.getDeclaredFields() )
                {
                    if( (field.getModifiers() & Modifier.STATIC) == 0 
                            && !field.getType().isPrimitive() )
                    {
                        field.setAccessible( true );
                        try
                        {
                            Object val = field.get( object );
                            if( val != null && visited.put( val, val ) == null )
                            {
                                stack.add( val );
                            }
                        }
                        catch( IllegalArgumentException e )
                        {
                            throw new RuntimeException( e );
                        }
                        catch( IllegalAccessException e )
                        {
                            throw new RuntimeException( e );
                        }
                    }
                }
            }
        }

        return shallowSizeOf( object );
    }
}

আপনি কি এই শ্রেণীর মান দিয়ে পরীক্ষা করেছেন? আমি চেষ্টা করেছি, কিন্তু আমার জন্য, ভুল মানগুলি !!!।
ডিবোরা

1
এটি একটি সাধারণ অবজেক্টের জন্য আমাকে যে মান দিয়েছে তা সঠিক ছিল তবে 1 মিও অবজেক্টযুক্ত তালিকার জন্য 10 এর একটি ফ্যাক্টর দ্বারা বন্ধ ছিল। তবুও, খুব সুন্দর কাজ!
মাইকেল বেকলিং

মজাদার. আমি জেডিকে 7 ইউ 67 ব্যবহার করে এটি উইন্ডোজ 7 এক্স 64 এবং লিনাক্স 2.6.16 / x86_64 ব্যবহার করে 32 বিট / 64 বিট / ওওপি অ্যাড্রেস মোডগুলির প্রত্যেকটি ব্যবহার করেছি। আমি এটিকে ক্লিপস মেমরি বিশ্লেষক 1.3.x এ বিশ্লেষণ করা মেমরি ডাম্পগুলির সাথে তুলনা করেছি। আপনি কোন সেটআপ ব্যবহার করছেন? আমি চেষ্টা করতে পারে একটি নির্দিষ্ট উদাহরণ আছে?
dlaudams

সেরা পছন্দ আমি করতে পারি। আমি ব্যবহার Instrumentationকরতে পারি না কারণ আমি টোমক্যাট শুরু করি না, ObjectSizeCalculatorকারণ ভিএম টাইপ (হটস্পট) এবং JOLব্যসাউস স্প্রিং মটরশুটি সম্পর্কে নিশ্চিত নয়। আমি এটি ব্যবহার করি এবং ক্লাস এবং AbstractRefreshableApplicationContext.getBeanFactory().getSingletonMutex()internalSizeOf
এনুম

ফলাফলের তুলনা করার জন্য অবজেক্টসাইজক্যালকুলেটর (পুরো সার্ভার 1 জিবি থেকে 10 সেকেন্ডে গণনা করুন) ব্যবহার করুন। জোলের কারণে মেমেরার (6 জিবি এনভনড হবে না) হয়ে থাকে এবং আমি একই ফলাফল পাই না, সম্ভবত এনমুসের কারণে।
পার্লোস

3

আমি কোনও প্রয়োজনীয় আকারের একটি রানটাইম গণনা খুঁজছিলাম যা নিম্নলিখিত প্রয়োজনীয়তাগুলি পূরণ করে:

  • উপকরণ অন্তর্ভুক্ত করার প্রয়োজন ছাড়া রানটাইম এ উপলব্ধ।
  • অসম্পূর্ণ অ্যাক্সেস ছাড়াই জাভা 9+ এর সাথে কাজ করে।
  • শুধুমাত্র ক্লাস উপর ভিত্তি করে। স্ট্রিং দৈর্ঘ্য, অ্যারের দৈর্ঘ্য, ইত্যাদি বিবেচনায় নেয় এমন কোনও গভীর আকার নয় O

নিম্নলিখিতটি মূল জাভা বিশেষজ্ঞের নিবন্ধের মূল কোড ( https: //www.javasp विशेषज्ञists.eu/archive/Issue078.html) এবং এই প্রশ্নের অন্য উত্তরে অনিরাপদ সংস্করণ থেকে কয়েকটি বিট ভিত্তিক is

আমি আশা করি যে কেউ এটি দরকারী হবে।

public class JavaSize {

private static final int NR_BITS = Integer.valueOf(System.getProperty("sun.arch.data.model"));
private static final int BYTE = 8;
private static final int WORD = NR_BITS / BYTE;
private static final int HEADER_SIZE = 8;

public static int sizeOf(Class<?> clazz) {
    int result = 0;

    while (clazz != null) {
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            if (!Modifier.isStatic(fields[i].getModifiers())) {
                if (fields[i].getType().isPrimitive()) {
                    Class<?> primitiveClass = fields[i].getType();
                    if (primitiveClass == boolean.class || primitiveClass == byte.class) {
                        result += 1;
                    } else if (primitiveClass == short.class) {
                        result += 2;
                    } else if (primitiveClass == int.class || primitiveClass == float.class) {
                        result += 4;
                    } else if (primitiveClass == double.class || primitiveClass == long.class) {
                        result += 8;
                    }

                } else {
                    // assume compressed references.
                    result += 4;
                }
            }
        }

        clazz = clazz.getSuperclass();

        // round up to the nearest WORD length.
        if ((result % WORD) != 0) {
            result += WORD - (result % WORD);
        }
    }

    result += HEADER_SIZE;

    return result;
}

}


2

কোনও মেথড কল নেই, যদি আপনি যা চাইছেন তা যদি হয়। একটু গবেষণা করে, আমি মনে করি আপনি নিজের লেখা লিখতে পারেন। একটি নির্দিষ্ট উদাহরণে রেফারেন্সের সংখ্যা এবং আদিম মানগুলি এবং উদাহরণ বুককিপিংয়ের ডেটা থেকে প্রাপ্ত একটি নির্দিষ্ট আকার রয়েছে। আপনি কেবল অবজেক্টের গ্রাফটি হাঁটাবেন। সারি ধরণের প্রকারগুলি যত কম তত সহজ।

যদি এটি খুব ধীর হয় বা এটির মূল্য অপেক্ষা আরও বেশি সমস্যা হয় তবে সর্বদা পুরানো rowষধের সারি গণনা নিয়ম-এর-থাম্বস।


2

আমি উড়তে অনুমান করার জন্য একবার দ্রুত পরীক্ষা লিখেছি:

public class Test1 {

    // non-static nested
    class Nested { }

    // static nested
    static class StaticNested { }

    static long getFreeMemory () {
        // waits for free memory measurement to stabilize
        long init = Runtime.getRuntime().freeMemory(), init2;
        int count = 0;
        do {
            System.out.println("waiting..." + init);
            System.gc();
            try { Thread.sleep(250); } catch (Exception x) { }
            init2 = init;
            init = Runtime.getRuntime().freeMemory();
            if (init == init2) ++ count; else count = 0;
        } while (count < 5);
        System.out.println("ok..." + init);
        return init;
    }

    Test1 () throws InterruptedException {

        Object[] s = new Object[10000];
        Object[] n = new Object[10000];
        Object[] t = new Object[10000];

        long init = getFreeMemory();

        //for (int j = 0; j < 10000; ++ j)
        //    s[j] = new Separate();

        long afters = getFreeMemory();

        for (int j = 0; j < 10000; ++ j)
            n[j] = new Nested();

        long aftersn = getFreeMemory();

        for (int j = 0; j < 10000; ++ j)
            t[j] = new StaticNested();

        long aftersnt = getFreeMemory();

        System.out.println("separate:      " + -(afters - init) + " each=" + -(afters - init) / 10000);
        System.out.println("nested:        " + -(aftersn - afters) + " each=" + -(aftersn - afters) / 10000);
        System.out.println("static nested: " + -(aftersnt - aftersn) + " each=" + -(aftersnt - aftersn) / 10000);

    }

    public static void main (String[] args) throws InterruptedException {
        new Test1();
    }

}

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

nested:        160000 each=16
static nested: 160000 each=16

সারিবদ্ধ আচরণ এবং সম্ভাব্য হিপ ব্লক শিরোলেখের ওভারহেড প্রদত্ত আমরা যা প্রত্যাশা করি।

গৃহীত উত্তরে বিশদ উপকরণ পদ্ধতিটি এখানে সবচেয়ে নির্ভুল। আমি যে পদ্ধতিটি বর্ণনা করেছি তা নির্ভুল তবে কেবল নিয়ন্ত্রিত অবস্থার অধীনে যেখানে অন্য কোনও থ্রেড বস্তু তৈরি / ছাড়ছে না।


2

শুধু জাভা ভিজ্যুয়াল ভিএম ব্যবহার করুন।

এতে আপনার প্রোফাইল এবং ডিবাগ মেমরির সমস্যাগুলির জন্য প্রয়োজনীয় সমস্ত কিছু রয়েছে।

এটিতে একটি ওকিউএল (অবজেক্ট কোয়েরি ল্যাঙ্গুয়েজ) কনসোল রয়েছে যা আপনাকে অনেক দরকারী জিনিস করতে দেয়, যার মধ্যে একটি sizeof(o)


1

আমার উত্তর নিক দ্বারা সরবরাহিত কোডের উপর ভিত্তি করে। এই কোডটি সিরিয়ালযুক্ত বস্তুর দ্বারা দখল করা মোট বাইটের পরিমাণ পরিমাপ করে। সুতরাং এটি আসলে সিরিয়ালাইজেশন স্টাফগুলি পরিমাপ করে + প্লেইন অবজেক্ট মেমরির পদচিহ্নগুলি (উদাহরণস্বরূপ কেবল সিরিয়ালাইজ করুন intএবং আপনি দেখতে পাবেন যে ক্রমিকায়িত বাইটের মোট পরিমাণ নেই 4)। সুতরাং আপনি যদি নিজের বস্তুর জন্য সঠিকভাবে কাঁচা বাইট নম্বর ব্যবহার করতে চান - আপনাকে সেই কোডটি কিছুটা পরিবর্তন করতে হবে। তাই ভালো:

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ObjectSizeCalculator {
    private Object getFirstObjectReference(Object o) {
        String objectType = o.getClass().getTypeName();

        if (objectType.substring(objectType.length()-2).equals("[]")) {
            try {
                if (objectType.equals("java.lang.Object[]"))
                    return ((Object[])o)[0];
                else if (objectType.equals("int[]"))
                    return ((int[])o)[0];
                else
                    throw new RuntimeException("Not Implemented !");
            } catch (IndexOutOfBoundsException e) {
                return null;
            }
        }

        return o;
    } 

    public int getObjectSizeInBytes(Object o) {
        final String STRING_JAVA_TYPE_NAME = "java.lang.String";

        if (o == null)
            return 0;

        String objectType = o.getClass().getTypeName();
        boolean isArray = objectType.substring(objectType.length()-2).equals("[]");

        Object objRef = getFirstObjectReference(o);
        if (objRef != null && !(objRef instanceof Serializable))
            throw new RuntimeException("Object must be serializable for measuring it's memory footprint using this method !");

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(o);
            oos.close();
            byte[] bytes = baos.toByteArray();

            for (int i = bytes.length - 1, j = 0; i != 0; i--, j++) {
                if (objectType != STRING_JAVA_TYPE_NAME) {
                    if (bytes[i] == 112)
                        if (isArray)
                            return j - 4;
                        else
                            return j;
                } else {
                    if (bytes[i] == 0)
                        return j - 1;
                }
            }
        } catch (Exception e) {
            return -1;
        }

        return -1;
    }    

}

আমি এই সমাধানটি আদিম ধরণের, স্ট্রিং এবং কিছু তুচ্ছ শ্রেণীর সাথে পরীক্ষা করেছি। আচ্ছাদিত মামলাও নাও থাকতে পারে।


আপডেট: উদাহরণ অ্যারে অবজেক্টের মেমরি পদচিহ্ন গণনা সমর্থন করার জন্য সংশোধিত।


1

জেটব্রেইনস ইন্টেলিজিজ ব্যবহার করার সময়, প্রথমে ফাইলটিতে "মেমরি এজেন্ট সংযুক্ত করুন" সক্ষম করুন সেটিংস | নির্মাণ, কার্যকরকরণ, মোতায়েন | ডিবাগার।

ডিবাগ করার সময়, আগ্রহের একটি চলকটিতে ডান ক্লিক করুন এবং "পুনরায় আকারের গণনা করুন" নির্বাচন করুন: রেনটেড সাইজ গণনা করুন


0

আপনি হিপ ডাম্প তৈরি করতে পারেন (উদাহরণস্বরূপ জ্যাম্যাপ সহ) এবং তারপরে অবজেক্টের আকারগুলি অনুসন্ধান করতে আউটপুটটি বিশ্লেষণ করতে পারেন। এটি একটি অফলাইন সমাধান, তবে আপনি অগভীর এবং গভীর আকার ইত্যাদি পরীক্ষা করতে পারেন


0
long heapSizeBefore = Runtime.getRuntime().totalMemory();

// Code for object construction
...
long heapSizeAfter = Runtime.getRuntime().totalMemory();
long size = heapSizeAfter - heapSizeBefore;

আকার আপনাকে বস্তু তৈরির কারণে jvm এর মেমরির ব্যবহার বৃদ্ধি দেয় এবং এটি সাধারণত বস্তুর আকার।


যদি জিসি মাঝখানে চলে যায় // অবজেক্ট কনস্ট্রাকশন এর জন্য কোড? এখন সবসময় সঠিক ফলাফল পেতে পারে।
রাজুগাদু

0

এই উত্তরটি অবজেক্ট আকারের সাথে সম্পর্কিত নয়, তবে আপনি যখন বস্তুগুলিকে সমন্বিত করতে অ্যারে ব্যবহার করছেন; এটি বস্তুর জন্য কত মেমরির আকার বরাদ্দ করবে।

সুতরাং অ্যারে, তালিকা বা মানচিত্রের সমস্ত সংগ্রহ সত্যই বস্তুগুলি সংরক্ষণ করবে না (কেবলমাত্র আদিমগুলির সময়, সত্যিকারের বস্তুর মেমরির আকার প্রয়োজন), এটি কেবলমাত্র সেই বস্তুর জন্য রেফারেন্স সঞ্চয় করবে store

এখন Used heap memory = sizeOfObj + sizeOfRef (* 4 bytes) in collection

  • (4/8 বাইট) ওএস (32/64 বিট) এর উপর নির্ভর করে

প্রিমিটিভের

int   [] intArray    = new int   [1]; will require 4 bytes.
long  [] longArray   = new long  [1]; will require 8 bytes.

বস্তু

Object[] objectArray = new Object[1]; will require 4 bytes. The object can be any user defined Object.
Long  [] longArray   = new Long  [1]; will require 4 bytes.

আমি বলতে চাইছি সমস্ত অবজেক্টের রেফারেন্সের জন্য মেমরির মাত্র 4 বাইট দরকার। এটি স্ট্রিং রেফারেন্স বা ডাবল অবজেক্ট রেফারেন্স হতে পারে, তবে অবজেক্ট তৈরির উপর নির্ভর করে প্রয়োজনীয় মেমরিটি পৃথক হবে।

উদাহরণস্বরূপ) আমি যদি নীচের শ্রেণীর জন্য অবজেক্ট তৈরি করি ReferenceMemoryTestতবে 4 + 4 + 4 = 12 বাইটের মেমরি তৈরি হবে। আপনি যখন রেফারেন্সগুলি আরম্ভ করার চেষ্টা করছেন তখন মেমরিটি পৃথক হতে পারে।

 class ReferenceMemoryTest {
    public String refStr;
    public Object refObj;
    public Double refDoub; 
}

সুতরাং যখন অবজেক্ট / রেফারেন্স অ্যারে তৈরি করা হচ্ছে, তখন এর সমস্ত বিষয়বস্তু NULL রেফারেন্স সহ দখল করা হবে। এবং আমরা জানি প্রতিটি রেফারেন্সের জন্য 4 বাইট প্রয়োজন।

এবং পরিশেষে, নীচের কোডের জন্য মেমরি বরাদ্দ 20 বাইট।

রেফারেন্সমেমোরিস্টেস্ট রেফ 1 = নতুন রেফারেন্সমেমোরিস্টেস্ট (); (4 (রেফ 1) + 12 = 16 বাইট) রেফারেন্সমিওরিস্টেস্ট রেফ 2 = রেফ 1; (4 (রেফ 2) + 16 = 20 বাইট)


1
কীভাবে একটি 4 বাইট পূর্ণসংখ্যা এবং অজানা আকারের একটি অবজেক্ট রেফারেন্স 4 বাইটে ফিট করতে পারে?
লার্নের মারকুইস

@ ইজেপি আমি বলতে চাইছি সমস্ত বস্তুর রেফারেন্সের জন্য মেমরির মাত্র 4 বাইট দরকার। এটি স্ট্রিং রেফারেন্স বা ডাবল অবজেক্ট রেফারেন্স হতে পারে, তবে অবজেক্ট তৈরির উপর নির্ভর করে প্রয়োজনীয় মেমরিটি পৃথক হবে।
কানাগাভেলু সুগুমার

0

ধরুন আমি এর Complexমতো নামের একটি শ্রেণি ঘোষণা করি :

public class Complex {

    private final long real;
    private final long imaginary;

    // omitted
}

এই শ্রেণীর লাইভ দৃষ্টান্তগুলিতে কত স্মৃতি বরাদ্দ করা হয়েছে তা দেখার জন্য:

$ jmap -histo:live <pid> | grep Complex

 num     #instances         #bytes  class name (module)
-------------------------------------------------------
 327:             1             32  Complex

-4

JSONObject এর জন্য নীচের কোডটি আপনাকে সহায়তা করতে পারে।

`JSONObject.toString().getBytes("UTF-8").length`

বাইট আকারে ফেরত দেয়

আমি আমার JSONArray অবজেক্টের সাথে এটি কোনও ফাইলে লিখে পরীক্ষা করে দেখেছি। এটি বস্তুর আকার দিচ্ছে।


এটি কেবলমাত্র এমন বস্তুর জন্য কাজ করবে যা বেশিরভাগ স্ট্রিং থাকে।
ডেক্সটার লেগাস্পি 21

-6

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

আপনি যেভাবে করতে পারেন তার একটি উপায় হ'ল জিনিসটিকে কোনও ফাইলের কাছে সিরিয়ালাইজ করা এবং ফাইলটির আকারটি এইভাবে দেখুন:

Serializable myObject;
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("obj.ser"));
oos.write (myObject);
oos.close ();

অবশ্যই, এটি ধরে নিয়েছে যে প্রতিটি বস্তুর স্বতন্ত্র এবং অন্য কোনও কিছুর অস্থায়ী তথ্য নেই।

আর একটি কৌশল হ'ল প্রতিটি বিষয়বস্তু নিয়ে যাওয়া এবং তার সদস্যদের প্রতিবিম্ব দ্বারা পরীক্ষা করা এবং মেম্বারশিপক্রমক্রমের নীচে কাজ করে আকারগুলি (বুলিয়ান এবং বাইট = 1 বাইট, শর্ট এবং চর = 2 বাইট ইত্যাদি) যুক্ত করা। তবে এটি ক্লান্তিকর এবং ব্যয়বহুল এবং সিরিয়ালাইজেশন কৌশলটি একই কাজটি শেষ করে।


3
আমি এটি বাইটআরআউটপুট স্ট্রিম ব্যবহার করে একটি বাইট [] এ সিরিয়ালিয়াল করব। এটি কোনও ফাইলে লেখার চেয়ে অনেক দ্রুত হবে।
ScArcher2

@ কোরেতুগ্য কোনও বস্তুর বাইট আকার নির্ধারণ করা ইতিমধ্যে একটি ব্যয়বহুল কাজ। আকার নির্ধারণের জন্য প্রতিটি বস্তুকে ডিস্কে লেখা, এটি ক্রল করে
চলেছে

1
সিরিয়ালযুক্ত অবজেক্ট ফর্ম্যাট হিপ মেমরির অবজেক্টের বিন্যাসের সাথে সম্পূর্ণ আলাদা। সর্বাধিক উল্লেখযোগ্যভাবে, অবজেক্টের শ্রেণির (এবং এর সিরিয়ালাইজযোগ্য সুপারক্লাসগুলির সমস্ত) জন্য একটি বর্ণনাকারী প্রবাহে লিখিত। সুতরাং একটি সাধারণ উদাহরণ লিখতে java.lang.Integerপ্রায় 80 বাইট উত্পাদন হয়, যেখানে গাদা উপস্থাপনা সাধারণত 32 হয় (অবজেক্ট স্ট্রিম উপস্থাপনের বিপরীতে, হিপ উপস্থাপনা পয়েন্টার আকার এবং অবজেক্ট সারিবদ্ধের উপর নির্ভর করে)। বিপরীতে, সিরিয়ালযুক্ত nullরেফারেন্সের জন্য হ্যাপ মেমরির চার বা আট বাইটের পরিবর্তে একটি বাইট প্রয়োজন।
হলগার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.