স্ট্রিংয়ের সাথে "" সংযুক্তি কীভাবে স্মৃতি সঞ্চয় করে?


193

আমি এতে প্রচুর ডেটা সহ ভেরিয়েবল ব্যবহার করেছি, বলুন String data। আমি এই স্ট্রিংয়ের একটি ছোট অংশ নিম্নলিখিত উপায়ে ব্যবহার করতে চেয়েছি:

this.smallpart = data.substring(12,18);

কয়েক ঘন্টা ডিবাগিংয়ের পরে (একটি স্মৃতি ভিজ্যুয়ালাইজার সহ) আমি জানতে পেরেছিলাম যে অবজেক্টস ফিল্ড smallpartথেকে সমস্ত ডেটা মনে আছে data, যদিও এতে কেবল সাবস্ট্রিং রয়েছে।

আমি কোডটি যখন এতে পরিবর্তন করেছি:

this.smallpart = data.substring(12,18)+""; 

..সমস্যাটি সমাধান করা হয়েছে! এখন আমার অ্যাপ্লিকেশনটি খুব কম স্মৃতি ব্যবহার করে!

কীভাবে সম্ভব? কেউ কি এই ব্যাখ্যা করতে পারেন? আমি মনে করি এটি.স্মাল্ট পার্ট তথ্যের প্রতি রেফারেন্স রেখেছিল, তবে কেন?

আপডেট: আমি কীভাবে বড় স্ট্রিংটি সাফ করতে পারি? ডেটা = নতুন স্ট্রিং (ডেটা.সুবস্ট্রিং (0,100)) কাজটি করবে?


নীচে আপনার চূড়ান্ত অভিপ্রায় সম্পর্কে আরও পড়ুন: বড় স্ট্রিংটি প্রথম স্থান থেকে কোথায় এসেছে? যদি কোনও ফাইল বা ডাটাবেস সিএলওবি বা অন্য কিছু থেকে পড়েন তবে পার্সিংয়ের সময় আপনার যা পড়বে তা কেবল চারপাশে অনুকূল হবে।
পিএসপিড

4
আশ্চর্যজনক ... আমি জাভাতে 4 থেকে 5 বছরেরও বেশি সময় ধরে কাজ করছি, এখনও এটি আমার জন্য নতুন :) তথ্য ভাই জন্য ধন্যবাদ।
পার্থ

1
ব্যবহার করার একটি সূক্ষ্মতা আছে new String(String); দেখতে stackoverflow.com/a/390854/8946
লরেন্স ডল

উত্তর:


159

নিম্নলিখিতগুলি করছেন:

data.substring(x, y) + ""

একটি নতুন (ছোট) স্ট্রিং অবজেক্ট তৈরি করে এবং স্ট্রিং () দ্বারা তৈরি স্ট্রিংয়ের রেফারেন্সটি ছুঁড়ে দেয়, ফলে এটির আবর্জনা সংগ্রহ সক্ষম করে।

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

কটাক্ষপাত সাবস্ট্রিং () মেথড আরও তথ্যের জন্য JDK স্ট্রিং উৎস হবে।

সম্পাদনা: আপনার পরিপূরক প্রশ্নের উত্তর দেওয়ার জন্য, স্ট্রিং থেকে একটি নতুন স্ট্রিং তৈরি করা আপনার স্মৃতিশক্তি খরচ কমিয়ে দেবে, তবে আপনি যদি মূল স্ট্রিংয়ের কোনও রেফারেন্স বিন করেন না।

দ্রষ্টব্য (জানুয়ারী 2013) উপরের আচরণটি জাভা 7u6 এ পরিবর্তিত হয়েছে । ফ্লাইওয়েট প্যাটার্নটি আর ব্যবহার করা substring()হবে না এবং আপনার প্রত্যাশা অনুযায়ী কাজ করবে।


89
এটি খুব কম কয়েকটি ক্ষেত্রে একটি যেখানে String(String)কনস্ট্রাক্টর (যেমন স্ট্রিং কনস্ট্রাক্টর স্ট্রিংটি ইনপুট হিসাবে স্ট্রিং গ্রহণ করে) দরকারী: new String(data.substring(x, y))কার্যকরভাবে সংযোজন হিসাবে একই জিনিসটি করে ""তবে এটি অভিপ্রায়টি কিছুটা পরিষ্কার করে দেয়।
জোছিম সউর

3
ঠিক সুনির্দিষ্টভাবে বলা যায়, সাবস্ট্রিং valueমূল স্ট্রিংয়ের বৈশিষ্ট্য ব্যবহার করে । আমি মনে করি সে কারণেই রেফারেন্স রাখা হয়েছে।
ভ্যালেন্টিন রচার

@ বিশিবুশ - হ্যাঁ, এটা ঠিক। আমি বাস্তবায়নের বিশদগুলি প্রকাশ করতে চাইনি, তবে যা ঘটছে তা হ'ল।
ব্রায়ান অগ্নিউ

5
প্রযুক্তিগতভাবে এটি বাস্তবায়নের বিশদ। তবে তা হতাশাব্যঞ্জক, এবং প্রচুর লোককে খুঁজে বের করে।
ব্রায়ান অগ্নিউ

1
আমি অবাক হয়েছি যে দুর্বল রেফারেন্স বা এ জাতীয় ব্যবহার করে এটি জেডিকেতে অনুকূলিত করা সম্ভব কিনা। যদি আমি সর্বশেষ ব্যক্তি, যাকে এই চর প্রয়োজন [], এবং আমার কেবল এটির কিছুটা প্রয়োজন হয় তবে আমার অভ্যন্তরীণভাবে ব্যবহারের জন্য একটি নতুন অ্যারে তৈরি করুন।
ডাব্লুডাব্লু

28

আপনি যদি উত্সটির দিকে তাকান substring(int, int), আপনি দেখতে পাবেন যে এটি ফিরে আসে:

new String(offset + beginIndex, endIndex - beginIndex, value);

যেখানে valueআসল char[]। সুতরাং আপনি একটি নতুন স্ট্রিং পাবেন কিন্তু একই অন্তর্নিহিত সাথে char[]

আপনি যখন করেন data.substring() + "", আপনি একটি নতুন অন্তর্নিহিত একটি নতুন স্ট্রিং পাবেন char[]

প্রকৃতপক্ষে, আপনার ব্যবহারের ক্ষেত্রে একমাত্র পরিস্থিতি যেখানে আপনার String(String)কনস্ট্রাক্টর ব্যবহার করা উচিত :

String tiny = new String(huge.substring(12,18));

1
ব্যবহার করার একটি সূক্ষ্মতা আছে new String(String); দেখতে stackoverflow.com/a/390854/8946
লরেন্স ডল

17

আপনি যখন ব্যবহার করবেন substring, এটি আসলে নতুন স্ট্রিং তৈরি করে না। এটি এখনও আপনার অফসেট এবং আকারের সীমাবদ্ধতার সাথে আপনার মূল স্ট্রিংটিকে বোঝায়।

সুতরাং, আপনার মূল স্ট্রিংটি সংগ্রহ করার অনুমতি দেওয়ার জন্য আপনাকে একটি নতুন স্ট্রিং তৈরি করতে হবে (ব্যবহার করে new Stringবা যা পেয়েছেন)।


5

আমি মনে করি এটি.স্মাল্ট পার্ট তথ্যের প্রতি রেফারেন্স রেখেছিল, তবে কেন?

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

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

এটি ঠিক করার "সঠিক" উপায়টি হ'ল new String(String)কনস্ট্রাক্টর, অর্থাৎ

this.smallpart = new String(data.substring(12,18));

বিটিডাব্লু, সামগ্রিক সর্বোত্তম সমাধানটি হ'ল প্রথম স্থানে খুব বড় স্ট্রিং থাকা এবং ছোট অংশগুলিতে কোনও ইনপুট প্রক্রিয়াকরণ করা, একবারে কয়েক কিলোবাইট।


ব্যবহার করার একটি সূক্ষ্মতা আছে new String(String); দেখতে stackoverflow.com/a/390854/8946
লরেন্স ডল

5

জাভা স্ট্রিংগুলি অপরিবর্তনীয় বস্তু এবং একবার স্ট্রিং তৈরি হয়ে গেলে, ময়লা আবদ্ধকারী দ্বারা এটি পরিষ্কার না করা অবধি স্মৃতিতে থেকে যায় (এবং এই পরিষ্কারকরণটি আপনি মঞ্জুর করে নিতে পারেন না)।

আপনি যখন স্ট্রিংয়ের পদ্ধতিটি কল করবেন তখন জাভা ট্রুলি নতুন স্ট্রিং তৈরি করে না, কেবল মূল স্ট্রিংয়ের অভ্যন্তরে কেবলমাত্র কয়েকটি অক্ষর সংরক্ষণ করে।

সুতরাং, আপনি যখন এই কোডটি দিয়ে একটি নতুন স্ট্রিং তৈরি করেছেন:

this.smallpart = data.substring(12, 18) + ""; 

আপনি যখন খালি স্ট্রিংয়ের সাথে ফলাফলটি মিলিয়েছিলেন তখন আপনি আসলে একটি নতুন স্ট্রিং তৈরি করেছিলেন। এই জন্য.


3

1997 সালে jwz দ্বারা নথিভুক্ত হিসাবে :

আপনার যদি বিশাল স্ট্রিং থাকে তবে এর একটি স্ট্রিং () টানুন, স্ট্রিংটিতে ধরে থাকুন এবং দীর্ঘ স্ট্রিংটিকে আবর্জনা হয়ে উঠতে দিন (অন্য কথায়, স্ট্রিংয়ের দীর্ঘকালীন জীবনকাল থাকে) বিশাল স্ট্রিংয়ের অন্তর্নিহিত বাইটগুলি কখনই যায় না দূরে।


2

কেবল সংক্ষেপে, যদি আপনি অল্প সংখ্যক বড় স্ট্রিং থেকে প্রচুর সাবস্ট্রিং তৈরি করেন তবে ব্যবহার করুন

   String subtring = string.substring(5,23)

যেহেতু আপনি কেবল বড় বড় স্ট্রিংগুলি সঞ্চয় করার জন্য জায়গাটি ব্যবহার করেন তবে আপনি যদি বড় স্ট্রিংয়ের লোস্টগুলি থেকে কিছুটা ছোট ছোট স্ট্রিং বের করছেন, তবে

   String substring = new String(string.substring(5,23));

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

আপনি যে কল করেছেন new Stringএটি একটি সহায়ক অনুস্মারক যে আপনি আসলটির সাথে উল্লেখ না করে সত্যই নতুন স্ট্রিং পাচ্ছেন।


ব্যবহার করার একটি সূক্ষ্মতা আছে new String(String); দেখতে stackoverflow.com/a/390854/8946
লরেন্স ডল

2

প্রথমত, কলিং java.lang.String.substringStringঅন্তর্নিহিত অ্যারের উল্লেখযোগ্য অংশটি অনুলিপি না করে অফসেট এবং দৈর্ঘ্যের ব্যবহারের সাথে মূলটিতে নতুন উইন্ডো তৈরি করে

আমরা যদি substringপদ্ধতিটি ঘনিষ্ঠভাবে পর্যালোচনা করি তবে আমরা স্ট্রিং কনস্ট্রাক্টর কলটি লক্ষ্য করব String(int, int, char[])এবং স্ট্রিংটিchar[] উপস্থাপন করে যা পুরোটি পাস করবে । তার মানে সাবস্ট্রিং মূল যেমন মেমরি অনেক পরিমাণ যেমন ব্যাপৃত হবে স্ট্রিং

ঠিক আছে, তবে কেন + ""এটির চেয়ে কম মেমরির চাহিদা কম ??

+অন করণ পদ্ধতি কলের stringsমাধ্যমে কার্যকর করা হয় StringBuilder.appendAbstractStringBuilderক্লাসে এই পদ্ধতির বাস্তবায়নটি দেখুন আমাদের বলবেন যে এটি শেষ পর্যন্ত arraycopyআমাদের কেবল সত্যই (অংশীদারি substring) অংশটির সাথে করে ।

অন্য কোন কাজ ??

this.smallpart = new String(data.substring(12,18));
this.smallpart = data.substring(12,18).intern();

0

স্ট্রিংয়ের সাথে "" যুক্ত করা কখনও কখনও স্মৃতি সঞ্চয় করে।

ধরা যাক আমার কাছে একটি বিশাল স্ট্রিং রয়েছে পুরো বইটি, এক মিলিয়ন অক্ষর।

তারপরে আমি সাবস্ট্রিং হিসাবে বইয়ের অধ্যায়গুলি সহ 20 টি স্ট্রিং তৈরি করি create

তারপরে আমি সমস্ত অনুচ্ছেদ সহ 1000 টি স্ট্রিং তৈরি করি।

তারপরে আমি সমস্ত বাক্য সম্বলিত 10,000 টি স্ট্রিং তৈরি করি।

তারপরে আমি সমস্ত শব্দ যুক্ত 100,000 স্ট্রিং তৈরি করি।

আমি এখনও কেবল 1,000,000 অক্ষর ব্যবহার করি। আপনি যদি প্রতিটি অধ্যায়, অনুচ্ছেদ, বাক্য এবং শব্দে "" যোগ করেন তবে আপনি 5,000,000 অক্ষর ব্যবহার করেন।

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

যদি আপনার দশ মিলিয়ন অক্ষরযুক্ত স্ট্রিং থাকে এবং উভয় প্রান্তে ট্যাব এবং স্পেসগুলি সরিয়ে ফেলুন, তবে স্ট্রিং তৈরি করতে 10 টি কল করুন। জাভা যেভাবে কাজ করে বা কাজ করে তা প্রতিবার মিলিয়ন অক্ষর অনুলিপি করা এড়ানো যায়। আপোস রয়েছে, এবং সমঝোতা কী তা আপনি যদি জানেন তবে তা ভাল।

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