JavaRush /Java Blog /Random-ID /substring(..) menghantuiku
IgorBrest
Level 33

substring(..) menghantuiku

Dipublikasikan di grup Random-ID
Sebenarnya, karena alasan subjeknya, saya membiarkan diri saya mempelajari String.substring(..). Dan saya mungkin mendapatkan hasil yang tidak terduga, yang saya putuskan untuk dibagikan kepada Anda, orang-orang Javorashov yang terkasih. Sampaikan saja sesuai penilaian Anda. Jadi begini. Ada pernyataan bahwa string yang dibuat menggunakan metode substring(..) menggunakan array karakter dari string asli. Di sini, khususnya, adalah kutipan dari artikel yang baru-baru ini dibaca "Referensi Java. String Statis" oleh artikel-artikel terkemuka :
Ada catatan tentang metode substring - string yang dikembalikan menggunakan array byte yang sama dengan yang asli
Dan tentu saja, Kuliah Javarash. Berikut kutipan dari 22 Desember:
Saat kita membuat substring menggunakan metode substring, objek String baru akan dibuat. Namun alih-alih menyimpan referensi ke array dengan kumpulan karakter baru, objek ini menyimpan referensi ke array karakter lama dan pada saat yang sama menyimpan dua variabel yang menentukan bagian mana dari array karakter asli yang menjadi miliknya. ... Saat substring dibuat, array karakter tidak disalin ke objek String baru. Sebaliknya, kedua objek menyimpan referensi ke array karakter yang sama. Tetapi! Objek kedua menyimpan dua variabel lagi, yang berisi karakter mana dan berapa banyak dari array ini yang ditulis ke dalamnya. ... Oleh karena itu, jika Anda mengambil string dengan panjang 10.000 karakter dan membuat 10.000 substring dengan panjang berapa pun, maka "substring" ini akan memakan sedikit memori, karena array karakter tidak diduplikasi. String yang seharusnya memakan banyak ruang hanya akan memakan beberapa byte.
semuanya tertulis dengan jelas, bahkan dikunyah. Tapi, karena saya mencoba untuk meningkatkan pengetahuan saya tentang bahasa Inggris, saya sering membuka dokumentasi resmi, dan entah bagaimana saya tidak dapat menemukan konfirmasi atas fakta ini... Mengaitkan ini dengan kecerobohan saya, saya masih melihat kode sumber dari substring() (berkat IDEA memungkinkan Anda melakukan ini dengan satu klik tombol). public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > value.length) { throw new StringIndexOutOfBoundsException(endIndex); } int subLen = endIndex - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); } Penasaran, saya melangkah lebih jauh: * Allocates a new {@code String} that contains characters from a subarray * of the character array argument. The {@code offset} argument is the * index of the first character of the subarray and the {@code count} * argument specifies the length of the subarray. The contents of the * subarray are copied; subsequent modification of the character array does * not affect the newly created string. public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); } di mana Arrays.copyOfRange adalah metode asli yang mengembalikan salinan array dari char... Kode yang cukup sepele, dan tampak jelas bagi saya bahwa baris baru dengan kumpulan karakter baru baru saja dibuat. atau saya tidak memperhitungkan sesuatu... Jadi, karena tidak sepenuhnya percaya pada kesimpulan saya, saya memutuskan untuk menguji substring() ini, dengan mengandalkan frasa dari kuliah:
Oleh karena itu, jika Anda mengambil string sepanjang 10.000 karakter dan membuat 10.000 substring dengan panjang berapa pun, maka “substring” ini akan memakan sedikit memori...
hanya dari 10_000 kita akan langsung menghasilkan 100_000_000, buat apa buang waktu untuk hal-hal sepele. Saya segera memasukkan kode berikut: dan inilah yang terjadi: mis. Setiap kali Anda membuat sub string baru menggunakan bigString.substring(..), array karakternya DUPLIKAT. Bagaimana lagi kita bisa menjelaskan peningkatan konsumsi memori? Setelah ini, saya pribadi tidak lagi ragu mengenai pengoperasian metode String.substsring(). Bagaimana dengan Anda? public class Test { public static void main(String[] args) { System.out.println("Начинаем:"); print(); System.out.println("********************************"); char[]big=new char[100_000_000];//создаем нормальный такой массив int j=0;//и заполняем этот массив всякой ерундой for (int k=0;k list=new ArrayList<>();//здесь будут ссылки на строки, что бы сборщик мусора не удалял //не используемые, по его мнению, строки. System.out.println("************************************"); System.out.println("Теперь будем создавть подстроки с помощью substring(..) и наблюдать," + "что же происходит с памятью"); for (int i = 2; i <10; i++) { //создаем подстроку, используя метод String.substring(..) String sub= bigString.substring(1,bigString.length()-1); //если этот метод не создает fully новый массив символов, а только пользуется //исходным из bigString // то при создании новой строки sub мы не будем наблюдать ощутипый расход памяти list.add(sub);//эти ссылки мы должны где нибудь хранить, иначе сборщик мусора //избавится от неипользуемых объктов String System.out.print(String.format("Создаем %d-ую подстроку, при этом ", i - 1)); print(); } System.out.println("***************************************"); print(); } static void print(){ System.out.println("Памяти используется "+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024 + " mb"); } } Начинаем: Памяти используется 0 mb ******************************** создал большую строку bigString на основе массива big. Теперь: Памяти используется 382 mb ************************************ Теперь будем создавть подстроки с помощью substring(..) и наблюдать,что же происходит с памятью Добавляем 1-ую подстроку, при этом Памяти используется 573 mb Добавляем 2-ую подстроку, при этом Памяти используется 763 mb Добавляем 3-ую подстроку, при этом Памяти используется 954 mb Добавляем 4-ую подстроку, при этом Памяти используется 1145 mb Добавляем 5-ую подстроку, при этом Памяти используется 1336 mb Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Arrays.java:3658) at java.lang.String. (String.java:201) at java.lang.String.substring(String.java:1956) at com.javarush.test.tests.Test.main(Test.java:42) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) Process finished with exit code 1
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION