Java의 힙은 클래스 객체가 공간을 할당하는 런타임 데이터 영역입니다. 이러한 객체는 new, newarray, anewarray 및 multianewarray와 같은 명령을 통해 생성되며 명시적으로 해제되는 프로그램 코드가 필요하지 않습니다. 힙의 장점은 메모리 크기를 동적으로 할당할 수 있다는 점이며 런타임에 메모리를 동적으로 할당하고 Java의 가비지 수집기가 더 이상 사용되지 않는 메모리를 자동으로 수집하므로 수명을 컴파일러에 미리 알릴 필요가 없다는 것입니다. 하지만 단점은 런타임 시 메모리의 동적 할당으로 인해 액세스 속도가 느리다는 것입니다.
스택의 장점은 레지스터에 이어 액세스 속도가 힙보다 빠르다는 것입니다. , 스택 데이터를 공유할 수 있지만 스택에 저장되는 데이터의 크기와 수명을 결정해야 하며 스택에는 주로 일부 기본 유형의 변수(int, short)가 저장된다는 점이 단점입니다. , long, byte, float, double, boolean, char) 및 객체 핸들
스택의 매우 중요한 특징은 스택에 저장된 데이터를 동시에 정의할 수 있다는 것입니다. :
int a = 3; int b = 3;
컴파일러는 먼저 int a = 3을 처리합니다. ; 먼저 스택에 변수 a에 대한 참조를 만든 다음 스택에 값 3이 있는지 확인합니다. 발견되지 않으면 3을 저장한 다음 a를 3으로 지정하고 생성하기 전에 int b = 3을 처리합니다. 스택에 이미 3의 값이 있으므로 b는 이 방법으로 a와 b는 동시에 3을 가리킵니다. 이때 Let a=4이면 컴파일러는 스택에 4 값이 있는지 다시 검색합니다. 그렇지 않은 경우 4를 저장하고 4를 지정합니다. 이미 존재하는 경우 a는 이 주소를 직접 가리킵니다.
이런 종류의 데이터 공유는 동시에 하나의 객체를 가리키는 두 객체의 참조를 공유하는 것과 다르다는 점에 유의해야 합니다. 이 경우 a의 수정은 b에 영향을 주지 않고 다음과 같이 수행되기 때문입니다. 공간 절약에 도움이 되는 컴파일러입니다. 객체 참조 변수가 이 객체의 내부 상태를 수정하면 다른 객체 참조 변수에 영향을 미칩니다.
문자열은 두 가지로 생성될 수 있습니다. form:
String str = new String("abc"); String str = "abc";
클래스의 값이 같은지 비교할 때는 equals() 메서드를 사용하고, 두 값을 테스트할 때는 . 두 패키지 클래스의 참조가 동일한 객체를 가리키는 경우 ==를 사용합니다. 다음에서는 위의 이론을 설명하기 위해 예제를 사용합니다.
String str1 = "abc"; String str2 = "abc";
String str1 =new String ("abc"); String str2 =new String ("abc"); System.out.println(str1==str2); // false
반면, String str = "abc";와 같은 형식을 사용하여 클래스를 정의할 때 항상 String 클래스의 객체 str이 생성된다고 가정합니다. 함정 걱정! 개체가 생성되지 않았을 수 있습니다! 이전에 생성된 개체를 가리킬 수도 있습니다. new() 메소드를 통해서만 매번 새로운 객체가 생성되도록 보장할 수 있습니다.
String 클래스의 불변성으로 인해 String 변수의 값을 자주 변경해야 하는 경우 StringBuffer 클래스를 사용하여 프로그램 효율성을 높이는 것이 좋습니다. Java의 힙은 클래스 객체가 공간을 할당하는 런타임 데이터 영역입니다. 이러한 객체는 new, newaray, multianewarray와 같은 명령을 통해 생성되며 힙은 가비지 수집을 담당하지 않습니다. 힙의 장점은 메모리 크기를 동적으로 할당할 수 있다는 점이며, 런타임에 동적으로 메모리를 할당하고 Java의 가비지 수집기가 자동으로 메모리 크기를 할당하지 않기 때문에 수명을 컴파일러에 미리 알릴 필요가 없다는 것입니다. 단점은 런타임 시 메모리의 동적 할당으로 인해 액세스 속도가 느리다는 것입니다.
b.jvm只有一个堆区被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:
a.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
b.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
c.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
a.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
b.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。字符串常量在方法区分配 ,数组既在栈空间分配数组名称, 又在堆空间分配数组实际的大小。
上面明白之后,接下来我们来分析 String str=new String("abc");
String str 是定义了一个String类型的变量,此时只定义了而没有创建对象,而new Sring(“abc”)到底做了什么?我们可以查看String的源码,发现如下:
public final class String
implements java.io.Serializable, Comparable
{
/** The value is used for character storage. */
private final char value[];
……
发现她有一个Value的属性,类型是char[],而此数组又做了什么事情?如果读源码会发现他保存了String对象的值,此时也说明String就是char[]来组织的。
当执行String a="abc";时,JAVA虚拟机会在栈中创建三个char型的值'a'、'b'和'c',然后在堆中创建一个String对象,它的值(value)是刚才在栈中创建的三个char型值组成的数组{'a','b','c'}对象,而这个新创建的String对象会被添加到字符串池中。
此时就存在了两个对象:一个在堆中;一个在字符串池中。
/**************************************************************************************************************************/
String str1 = "abc"; String str2 = new String("abc");
위 내용은 기본 유형과 캡슐화된 유형 데이터, Java의 힙 및 스택 간의 관계 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!