উত্তর:
মাইন্ডপ্রড উল্লেখ করেছেন যে এটি উত্তর দেওয়ার জন্য সোজা প্রশ্ন নয়:
কোনও জেভিএম কোনও পরিমাণে প্যাডিং বা ওভারহেড সহ কোনওভাবে অভ্যন্তরীণভাবে, বড় বা সামান্য এডিয়ান পছন্দ করে ডেটা সংরক্ষণ করতে পারে তবে আদিমদের অবশ্যই আচরণ করতে হবে যেমন তাদের সরকারী আকার রয়েছে।
উদাহরণস্বরূপ, জেভিএম বা নেটিভ সংকলক একটিboolean[]
এর মতো -৪-বিট দীর্ঘ অংশে একটি সঞ্চয় করার সিদ্ধান্ত নিতে পারেBitSet
। এটি আপনাকে বলার দরকার নেই, যতক্ষণ না প্রোগ্রামটি একই উত্তর দেয়।
- এটি স্ট্যাকের কিছু অস্থায়ী বিষয় বরাদ্দ করতে পারে।
- এটি কিছু পরিবর্তনশীল বা পদ্ধতি কলগুলি অস্তিত্বের বাইরে সম্পূর্ণরূপে তাদের স্থির করে প্রতিস্থাপন করে optim
- এটি সংস্করণ পদ্ধতি বা লুপগুলি, অর্থাত্ একটি পদ্ধতির দুটি সংস্করণ সংকলন করতে পারে, প্রতিটি একটি নির্দিষ্ট পরিস্থিতির জন্য অনুকূলিত হয়, তারপরে কোনটি কল করতে হবে তা সিদ্ধান্ত নেয়।
তারপরে অবশ্যই হার্ডওয়্যার এবং ওএসের মাল্টিলেয়ার ক্যাশে, চিপ-ক্যাশে, এসআরএএম ক্যাশে, ডিআরএএম ক্যাশে, সাধারণ র্যাম ওয়ার্কিং সেট এবং ডিস্কে ব্যাকিং স্টোর রয়েছে। আপনার ডেটা প্রতিটি ক্যাশে স্তরে নকল করা যেতে পারে। এই সমস্ত জটিলতার অর্থ আপনি কেবল মোটামুটিভাবে র্যাম ব্যবহারের পূর্বাভাস দিতে পারেন।
আপনি Instrumentation.getObjectSize()
কোনও বস্তুর দ্বারা গ্রাহিত স্টোরেজটির প্রাক্কলন অর্জন করতে ব্যবহার করতে পারেন ।
আসল অবজেক্ট লেআউট, পদচিহ্ন এবং উল্লেখগুলি কল্পনা করতে আপনি JOL (জাভা অবজেক্ট লেআউট) সরঞ্জামটি ব্যবহার করতে পারেন ।
একটি আধুনিক -৪-বিট জেডিকে, কোনও সামগ্রীতে একটি 12-বাইট শিরোলেখ থাকে, 8 টি বাইটের একাধিকতে প্যাড করা হয়, তাই সর্বনিম্ন অবজেক্টের আকার 16 বাইট হয়। 32-বিট জেভিএম-এর জন্য ওভারহেড 8 বাইট, 4 বাইটের একাধিক প্যাড করা হয়। (এইখান থেকে দিমিত্রি Spikhalskiy এর উত্তর , Jayen এর উত্তর , এবং JavaWorld ।)
সাধারণত, 32 বিট প্ল্যাটফর্মে বা 64 বিট প্ল্যাটফর্মগুলিতে রেফারেন্সগুলি 4 বাইট -Xmx32G
; এবং 8 বাইট 32 জিবি ( -Xmx32G
) এর উপরে । ( সঙ্কোচিত বস্তুর উল্লেখ দেখুন ।)
ফলস্বরূপ, একটি 64-বিট জেভিএম সাধারণত 30-50% বেশি হিপ স্থানের প্রয়োজন হয়। ( আমি কি 32- বা 64-বিট জেভিএম ব্যবহার করব ? , 2012, জেডিকে 1.7)
বাক্সযুক্ত মোড়কগুলির প্রারম্ভিক ধরণের তুলনায় ওভারহেড রয়েছে ( জাভা ওয়ার্ল্ড থেকে ):
Integer
: 16-বাইটের ফলাফলটি আমার প্রত্যাশার চেয়ে কিছুটা খারাপ কারণ কোনওint
মান মাত্র 4 টি অতিরিক্ত বাইটে ফিট করতে পারে।Integer
আমি যখন আদিম ধরণের হিসাবে মানটি সঞ্চয় করতে পারি তার তুলনায় একটি ব্যয় আমাকে 300 শতাংশ মেমরির ওভারহেড ব্যবহার করে
Long
: ১ by বাইটও: স্পষ্টতই, গাদাতে প্রকৃত অবজেক্টের আকারটি কোনও নির্দিষ্ট সিপিইউ টাইপের জন্য একটি জেভিএম প্রয়োগের দ্বারা স্বল্প স্তরের মেমরির প্রান্তিককরণের সাপেক্ষে। দেখে মনে হচ্ছেLong
অবজেক্টের ওভারহেডের 8 বাইট, প্রকৃত দীর্ঘ মানের জন্য 8 বাইট আরও বেশি। বিপরীতে,Integer
একটি অব্যবহৃত 4-বাইট গর্ত ছিল, সম্ভবত আমি যে JVM বাহিনী ব্যবহার করি 8-বাইট শব্দের বাউন্ডারে অবজেক্ট সারিবদ্ধ করি।
অন্যান্য পাত্রে খুব ব্যয়বহুল:
বহুমাত্রিক অ্যারে : এটি আরও একটি চমক দেয়।
বিকাশকারীরা সাধারণতint[dim1][dim2]
সংখ্যাসূচক এবং বৈজ্ঞানিক কম্পিউটিংয়ের মতো কনস্ট্রাক্টগুলিকে নিয়োগ করেন ।একটি
int[dim1][dim2]
অ্যারের উদাহরণে, প্রতিটি নেস্টেডint[dim2]
অ্যারেObject
তার নিজস্ব ডানদিকে। প্রতিটিতে সাধারণ 16-বাইট অ্যারে ওভারহেড যুক্ত হয়। আমার যখন ত্রিভুজাকার বা র্যাগড অ্যারে দরকার হয় না, যা খাঁটি ওভারহেড উপস্থাপন করে। প্রভাব অ্যারে মাত্রা ব্যাপকভাবে পৃথক যখন বৃদ্ধি।উদাহরণস্বরূপ, একটি
int[128][2]
উদাহরণ 3,600 বাইট নেয়। একটিint[256]
উদাহরণ ব্যবহার করে (যার একই ক্ষমতা রয়েছে) 1,040 বাইটের তুলনায় 3,600 বাইট একটি 246 শতাংশ ওভারহেড উপস্থাপন করে। চরম ক্ষেত্রেbyte[256][1]
, ওভারহেড ফ্যাক্টর প্রায় 19! সেটিকে সি / সি ++ এর সাথে তুলনা করুন যেখানে একই সিনট্যাক্স কোনও স্টোরেজ ওভারহেড যুক্ত করে না।
String
: একটিString
মেমরির বৃদ্ধি তার অভ্যন্তরীণ চর অ্যারের বৃদ্ধি ট্র্যাক করে। তবেString
ক্লাসটি ওভারহেডের আরও 24 বাইট যুক্ত করে।একটি nonempty জন্য
String
আকার 10 অক্ষর বা তার কমে, দরকারী পে লোড জুড়েছে ওভারহেড খরচ আপেক্ষিক (প্রতিটি গৃহস্থালির কাজ 2 বাইট প্লাস দৈর্ঘ্যের জন্য 4 বাইট), 100 থেকে 400 শতাংশ রেঞ্জ।
এই উদাহরণ বস্তু বিবেচনা করুন :
class X { // 8 bytes for reference to the class definition
int a; // 4 bytes
byte b; // 1 byte
Integer c = new Integer(); // 4 bytes for a reference
}
একটি নির্লজ্জ যোগফল একটি উদাহরণ X
17 বাইট ব্যবহার করবে যে প্রস্তাব করবে। তবে, প্রান্তিককরণের কারণে (প্যাডিংও বলা হয়), JVM মেমরিটি 8 বাইটের গুণিতকগুলিতে বরাদ্দ করে, তাই 17 বাইটের পরিবর্তে এটি 24 বাইট বরাদ্দ করবে would
এটি আর্কিটেকচার / জেডিকে নির্ভর করে। একটি আধুনিক জেডিকে এবং bit৪ বিট আর্কিটেকচারের জন্য, কোনও জিনিসে 12-বাইট শিরোনাম এবং 8 বাইট দ্বারা প্যাডিং রয়েছে - তাই সর্বনিম্ন অবজেক্টের আকার 16 বাইট হয়। আপনি কোনও আকার নির্ধারণ করতে এবং যেকোন সত্তার অভ্যন্তরীণ কাঠামো সম্পর্কে বিশদ পেতে বা শ্রেণি রেফারেন্স দ্বারা এই তথ্যটি অনুমান করার জন্য জাভা অবজেক্ট লেআউট নামক একটি সরঞ্জাম ব্যবহার করতে পারেন । আমার পরিবেশে পূর্ণসংখ্যার জন্য আউটপুট উদাহরণ:
Running 64-bit HotSpot VM.
Using compressed oop with 3-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]
java.lang.Integer object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 12 (object header) N/A
12 4 int Integer.value N/A
Instance size: 16 bytes (estimated, the sample instance is not available)
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
সুতরাং, পূর্ণসংখ্যার জন্য উদাহরণ আকার 16 বাইট, কারণ 4-বাইটস ইন্টিরিড ঠিক পরে শিরোনামের পরে এবং প্যাডিং বাউন্ডারি করার আগে জায়গায় কম্প্যাক্ট।
কোড নমুনা:
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.util.VMSupport;
public static void main(String[] args) {
System.out.println(VMSupport.vmDetails());
System.out.println(ClassLayout.parseClass(Integer.class).toPrintable());
}
আপনি জেওএল পাওয়ার জন্য মাভেন ব্যবহার করেন:
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.3.2</version>
</dependency>
প্রতিটি বস্তুর সাথে সম্পর্কিত মনিটর এবং টাইপ তথ্যের পাশাপাশি ক্ষেত্রগুলি নিজের জন্য একটি নির্দিষ্ট ওভারহেড থাকে। এর বাইরেও, ক্ষেত্রগুলি খুব ভাল স্থাপন করা যেতে পারে তবে জেভিএম ফিট দেখায় (আমি বিশ্বাস করি) - তবে অন্য উত্তরে দেখানো হয়েছে , কমপক্ষে কিছু জেভিএম মোটামুটি শক্তভাবে প্যাক করবে। এর মতো একটি শ্রেণী বিবেচনা করুন:
public class SingleByte
{
private byte b;
}
বনাম
public class OneHundredBytes
{
private byte b00, b01, ..., b99;
}
একটি 32-বিট জেভিএম-তে, আমি 12 টি SingleByte
বাইট (প্যাডিং / সারিবদ্ধকরণের কারণে মাঠের জন্য 8 বাইট ওভারহেড + 4 বাইট) নেওয়ার 100 টি উদাহরণ আশা করব । আমি OneHundredBytes
108 বাইট নেওয়ার একটি উদাহরণ আশা করব - ওভারহেড এবং তারপরে 100 বাইট, প্যাক করা। এটি অবশ্যই জেভিএম দ্বারা পরিবর্তিত হতে পারে - একটি বাস্তবায়ন ক্ষেত্রগুলি প্যাক না করার সিদ্ধান্ত নিতে পারে OneHundredBytes
, যার ফলে এটি ৪০৮ বাইট (= 8 বাইট ওভারহেড + 4 * 100 সারিবদ্ধ / প্যাডযুক্ত বাইট) নিতে পারে। একটি 64 বিট জেভিএম-তে ওভারহেডটি খুব বেশি বড় হতে পারে (নিশ্চিত নয়)।
সম্পাদনা: নীচে মন্তব্য দেখুন; স্পষ্টত হটস্পট প্যাডগুলি 32 এর পরিবর্তে 8 বাইট সীমানায় যাবে, সুতরাং প্রতিটি উদাহরণ SingleByte
16 বাইট লাগবে।
যে কোনও উপায়ে, "একক বৃহত বস্তু" কমপক্ষে একাধিক ছোট বস্তুর মতো দক্ষ হবে - এর মতো সাধারণ ক্ষেত্রে।
কোনও প্রোগ্রামের মোট ব্যবহৃত / নিখরচায় মেমোরি প্রোগ্রামের মাধ্যমে পাওয়া যায়
java.lang.Runtime.getRuntime();
রানটাইমের বিভিন্ন পদ্ধতি রয়েছে যা স্মৃতির সাথে সম্পর্কিত। নিম্নলিখিত কোডিং উদাহরণটি এর ব্যবহার দেখায়।
package test;
import java.util.ArrayList;
import java.util.List;
public class PerformanceTest {
private static final long MEGABYTE = 1024L * 1024L;
public static long bytesToMegabytes(long bytes) {
return bytes / MEGABYTE;
}
public static void main(String[] args) {
// I assume you will know how to create a object Person yourself...
List < Person > list = new ArrayList < Person > ();
for (int i = 0; i <= 100000; i++) {
list.add(new Person("Jim", "Knopf"));
}
// Get the Java runtime
Runtime runtime = Runtime.getRuntime();
// Run the garbage collector
runtime.gc();
// Calculate the used memory
long memory = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Used memory is bytes: " + memory);
System.out.println("Used memory is megabytes: " + bytesToMegabytes(memory));
}
}
এটি প্রদর্শিত হয় যে প্রতিটি অবজেক্টের 32-বিট সিস্টেমে 16 বাইটের ওভারহেড থাকে (এবং 64-বিট সিস্টেমে 24 বাইট)।
http://algs4.cs.princeton.edu/14analysis/ তথ্যগুলির একটি ভাল উত্স। অনেক ভাল ব্যক্তিদের মধ্যে একটি উদাহরণ নিম্নরূপ।
http://www.cs.virginia.edu/kim/publicity/pldi09t টিউটোরিয়ালস / মেমরি- দক্ষ-জাভা- টিউটোরিয়াল.পিডিএফ খুব তথ্যবহুল, উদাহরণস্বরূপ:
100 টি অ্যাট্রিবিউটের সাথে কোনও বস্তু দ্বারা ব্যবহৃত স্মৃতির স্থানটি 100 টি অবজেক্টের সাথে একই হিসাবে প্রতিটি বৈশিষ্ট্যের সাথে একই হয়?
না।
কোন বস্তুর জন্য কত স্মৃতি বরাদ্দ করা হয়?
একটি অ্যাট্রিবিউট যোগ করার সময় কত অতিরিক্ত স্থান ব্যবহার করা হয়?
প্রশ্ন একটি খুব বিস্তৃত হবে।
এটি শ্রেণীর ভেরিয়েবলের উপর নির্ভর করে বা আপনি জাভাতে মেমরির ব্যবহার হিসাবে কল করতে পারেন।
এটিতে শিরোনাম এবং রেফারেন্সিংয়ের জন্য কিছু অতিরিক্ত মেমরির প্রয়োজনীয়তাও রয়েছে।
একটি জাভা অবজেক্ট দ্বারা ব্যবহৃত হিপ মেমরি অন্তর্ভুক্ত
আদিম ক্ষেত্রগুলির জন্য মেমরি, তাদের আকার অনুসারে (আদিম ধরণের আকারগুলির জন্য নীচে দেখুন);
রেফারেন্স ক্ষেত্রগুলির জন্য মেমরি (প্রতিটি 4 বাইট);
"হাউজকিপিং" তথ্যের কয়েকটি বাইট সমন্বয়ে একটি অবজেক্ট শিরোনাম;
জাভাতে থাকা সামগ্রীর জন্য কিছু "গৃহকর্মী" তথ্য প্রয়োজন যেমন কোনও বস্তুর শ্রেণি রেকর্ড করা, আইডি এবং স্থিতির পতাকাগুলি যেমন বস্তুটি বর্তমানে পৌঁছনীয় কিনা তা বর্তমানে সিঙ্ক্রোনাইজেশন-লক করা ইত্যাদি etc.
জাভা অবজেক্ট শিরোনামের আকার 32 এবং 64 বিট jvm এ পরিবর্তিত হয়।
যদিও এগুলি মূল মেমরির ভোক্তা jvm এর জন্য অতিরিক্ত ক্ষেত্রগুলিরও প্রয়োজন হয় কখনও কখনও কোডের প্রান্তিককরণের জন্য
আদিম ধরণের আকার
বুলিয়ান এবং বাইট - 1
চর এবং সংক্ষিপ্ত - 2
ইন্ট ও ফ্লোট - 4
দীর্ঘ এবং ডাবল - 8
আমি জাভা.এল.ইং.ইনসেসমেন্টস থেকে খুব ভাল ফলাফল পেয়েছি another অন্য একটি উত্তরে উল্লিখিত nতুস্রাবের পদ্ধতিটি। এর ব্যবহারের ভাল উদাহরণগুলির জন্য, জাভাস্পেশালিস্টদের নিউজলেটার থেকে জাভাস্পিজালিস্টস নিউজলেটার এবং জাভা.সাইজঅফ লাইব্রেরি থেকে সোর্সফোর্সে এন্ট্রি, ইনস্ট্রুমেন্টেশন মেমরি কাউন্টার দেখুন ।
এটি কারও পক্ষে উপকারী হলে আপনি কোনও বিষয়বস্তুর স্মৃতি ব্যবহারের জন্য আপনার ওয়েব সাইট থেকে একটি ছোট জাভা এজেন্ট ডাউনলোড করতে পারেন । এটি আপনাকে "গভীর" মেমরির ব্যবহারের জন্যও জিজ্ঞাসা করতে দেবে।
(String, Integer)
পেয়ারা ক্যাশে, প্রতি-উপাদানটিতে কত স্মৃতি ব্যবহার করে তার মোটামুটি অনুমান করার জন্য এটি দুর্দান্ত কাজ করেছে । ধন্যবাদ!
কতটা মেমরি গ্রাস করা হয় সে সম্পর্কে নিয়মগুলি জেভিএম বাস্তবায়ন এবং সিপিইউ আর্কিটেকচারের উপর নির্ভর করে (উদাহরণস্বরূপ 32 বিট বনাম 64 বিট)।
সান জেভিএম সম্পর্কিত বিস্তারিত নিয়মের জন্য আমার পুরানো ব্লগটি পরীক্ষা করুন check
শুভেচ্ছা, মার্কাস