[英]How does JVM allocate this memory
如果您在Java中像这样声明字符串数组
String[] words;
那只是给您一个正确的参考?
现在,我来自C语言的背景,所以我知道C语言中的“字符串”数组是指向指针的指针,或者是数组的数组。 但是,我想知道JVM如何使用此声明...它只是一个引用吗? 然后,当您给它足够的内存时,它也会为字符串提供不同的长度吗?
我很难形容,但我知道字符串只是字符数组,因此JVM如何在分配字符串之前确定字符串有多长时间? 它是否以新的更新字符串长度重新分配整个字符串数组。
char array[6][6]; //in C this is necessary because it needs to know the column and row length
与此类似
char* array[5]; // you still need to malloc the slots in the array for a two dimensional length to be achieved
但是在Java中我不知道它如何工作
String line = null;
try {
while ((line = bfr.readLine()) != null) {
if (StringUtils.isBlank(line))
continue;
System.out.println(line);
String[] chunks = line.split(","); //this line right here, how does JVM allocate proper memory
MindsparkPartnerCode record = new MindsparkPartnerCode();
record.setIEFFCode(chunks[0]);
records.add(record);
好吧,您实际上是在问两个问题。
首先,在Java中声明一个数组(任何深度)都不会分配内存,而在您的C示例中,您声明并定义了一个数组,它会分配内存。
Java:
String[] words; // Just a reference (null at this point) -- no memory allocated
C:
char array[6][10]; // *Does* allocate 60 bytes of memory, usually on the stack.
在Java中,在使用new
运算符之前,不会分配任何内存(当然,对于基元除外)。
Foo bar; // Just a reference
bar = new Foo(); // NOW memory has been allocated.
new
返回对新对象的引用 。 将不是原始元素的所有内容都视为参考(包括数组!)。
字符串没有什么不同。
String[] foo;
...只是为字符串对象引用的数组的引用 。 而已。
即使您创建数组...
foo = new String[20];
... Java分配20 * sizeof(JavaReference)
字节(其中JavaReference
是JVM用于表示引用的任何基础类型)。 因此,现在知道数组的大小。
当您实际将字符串添加到该数组时...
foo[0] = "Hello!"; // Which is essentially...
foo[0] = new String("Hello!");
...... 那就是当你告诉你的JVM字符串有多长,从而告诉它分配(strlen("Hello!") + 1) * 2
个字节(因为Java的存储其字符串以UTF-16编码)。
还有,请记住, 字符串是不可变的,所以JVM不必担心realloc
“荷兰国际集团他们。
关于Java,关于字符串的问题很棘手,因为Java接受了另外一个类( String
),然后将其转换为语言结构(如最后一个代码示例所示)。 难怪在考虑内存和分配时字符串会造成混乱。
在Java中, String
不是字符数组。 它是对堆上类java.lang.String
垃圾回收实例的引用。 从文档:
String类表示字符串。 Java程序中的所有字符串文字(例如“ abc”)都实现为此类的实例。
字符串是常量; 它们的值创建后无法更改。 字符串缓冲区支持可变字符串。 由于String对象是不可变的,因此可以共享它们。 例如:
String str = "abc";
等效于:
char data[] = {'a', 'b', 'c'}; String str = new String(data);
String类包含一些方法,这些方法可以检查序列中的各个字符,比较字符串,搜索字符串,提取子字符串以及创建字符串的副本,并将所有字符都转换为大写或小写。 大小写映射基于Character类指定的Unicode标准版本。
Java语言为字符串连接运算符(+)以及将其他对象转换为字符串提供了特殊的支持。 字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。 字符串转换是通过toString方法实现的,该方法由Object定义并由Java中的所有类继承...
因此可以从一个字符数组创建一个String
,但它不仅仅是一个字符数组。 该类内置于Java本身,因此编译器知道如何从键入代码的字符串文字中实例化该类的实例。
因此,当您执行以下操作时:
String[] chunks = line.split(",");
您在类java.lang.String
的实例上调用split
方法。 它返回给您一个java.lang.String
对象数组, 该对象将自己分配 (数组和字符串)。 最终,当它们不再被引用时,将全部被垃圾回收。
String[] chunks = line.split(","); //this line right here, how does JVM allocate proper memory
在此语句完成时,将可以引用N + 1个新对象:
String[]
数组对象 String
对象,每个对象位于数组的每个插槽中 我也有一些C背景。 在Java中,某些事物的数组与C中的完全相同。它是一个指针数组(或仅是基本类型(如ints))。 数组的大小必须对Java一样可用,例如
String[] words = new String[10];
您的示例将单词声明为字符串数组,从而导致变量“ words”具有指向字符串数组的空指针。 我的示例将“单词”指向由10个指向字符串的指针组成的数组。
看看API java.util.arrays
https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html
它为其他堆对象分配一个引用数组。 Java中的大写S字符串本身就是对堆上对象的引用,而该对象又包含对char []的引用,该char []可以具有任意大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.