字符串的比较和JVM虚拟机内存分配

一.比较字符串:

可以用equals( )来进行字符串内容的比较,不能用”==“来比较字符串内容是否相等

String s1 = new String("hello");
String s2 = new String("hello");
System.out.prinln(s1.equals(s2));//在Object中,该方法比较的是对象的地址,
                                //而在String类中重写了该方法,比较的就是字符串的内容
        //输出:true
String s1 = new String("hello");
String s2 = new String("hello");//因为new了,就会产生不同的对象,
                                 //且每一个对象都会对应不同的地址,并且在堆区的字符串常量池中
System.out.println(s1==s2);//用”==“比较的是地址。  输出:false
String s1 = "Hello";
String s2 = "Hello";  //没有new,并且两个字符串的内容是相同的,所以在常量池中只有一个Hello
System.out.println(s1==s2);//输出:true
String s1 = "Java";  //存放在字符串常量池中
s1 += "程序";  //字符串经过运算后会回到堆内存中

二. JVM虚拟机内存分配

Java程序是运行在JVM(java虚拟机)上的,因此Java的内存分配是在JVM中进行的。那么在程序内存分配上面,大致分为:本地方法栈、程序计数器、虚拟机栈、java堆、方法区这五类,本次主要讲解的是虚拟机栈、Java堆和方法区中的内容。

:存放基本数据类型的数据、引用数据类型的变量名及对象的引用,但是引用的数据与对象并不放在栈中,而是放在堆中。(即放方法和变量)

:存放引用数据类型的数据与new出来的对象,注意创建出来的对象只包含各自的成员变量,不包括成员方法。

方法区:用于存储类的结构信息、常量、静态变量、编译器编译后的代码等数据。

字符串常量池:在JDK1.6及之前的版本,字符串常量池存放在方法区中间,在JDK1.7版本以后,字符串常量池就被移到堆中了。

JVM虚拟机内存的分配:
在这里插入图片描述
首先注意一下以下代码:

Demo demo;//创建对象引用
demo=/*将对象引用指向对象*/new Demo();//创建对象

请看下列代码,分析内存分配的过程:

public class Demo { //首先这是一个Demo类,那么在编译后会生成Demo.class文件,放在常量池中;
	String username; 
	public void method() {
        int i=1;
		System.out.println("执行类方法");
	}
	public static void main(String[] args) {//main方法是程序的主入口,那么在栈中会生成main方法的方法帧。
		int i=1; //执行第一行代码 int i=1; 由于int是基本数据类型,会在栈中给 i=1分配内存空间。
		String str="hello java"; //下面执行String……,由于String是引用数据类型,那么str变量名会放在栈中,但是里面的       
                                    //值"hello java"会放在方法区的常量池中。str指向hello java。
		Demo demo=new Demo(); //右边new了一个Demo对象,左边的“Demo demo”创建了一个Demo类引用变量,它存放在栈空间中。也就是用来指向堆中的new Demo(),堆中存入具体的对象属性
		demo.username="123"; //这就是堆中的 
		                      //具体属性,那么会在堆中存入“123”。
		demo.method();//会在栈里面又生成一个方法帧,由于栈的先进后出的特点,会先执行新的方法帧里面的内容,这时会执行method方法里的程序,打印输出执行类方法
		
	}
 
}

注意:方法帧出栈后,相对应的堆和方法区里的内容不会清空,会等到进程结束,垃圾回收机制会进行处理

在这里插入图片描述

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 字符串常量池在JVM中属于方法区(也称为永久代)内存分区。方法区是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。字符串常量池是方法区中的一部分,用于存储字符串常量。在JDK 8之后,方法区被取消了,取而代之的是元空间(MetaSpace),但字符串常量池仍然存放在元空间中。 ### 回答2: 字符串常量池在JVM的方法区(也称为非堆区)中。 JVM将内存分为几个不同的区域,包括堆区、方法区、虚拟机栈等。而字符串常量池是方法区的一部分,用于存储在程序中直接使用的字符串常量。 在Java中,字符串常量池是一种特殊的内存存储区域,用于存储字符串常量,它的作用是提高字符串的重用性和效率。当我们使用双引号声明一个字符串时,JVM会首先在字符串常量池中查找是否存在相同内容的字符串,如果存在则直接返回引用,如果不存在则创建一个新的字符串并放入字符串常量池中。这种机制可以减少内存占用,提高程序的执行效率。 由于字符串常量池位于方法区,它是与其他线程共享的,在程序运行过程中,多个线程可以同时访问字符串常量池。而且,字符串常量池的位置是在程序的执行过程中被动态调整的,当字符串没有被引用时,JVM会自动回收字符串常量池中的空间。 总结来说,字符串常量池是JVM的方法区的一部分,用于存储程序中直接使用的字符串常量,并提高字符串的重用性和效率。 ### 回答3: 字符串常量池在JVM的方法区里。方法区是JVM的一个内存分区,用于存储类信息、常量、静态变量、即时编译器编译后的代码等。而字符串常量池就是方法区的一部分,用于存储字符串常量。 在Java中,当我们使用字符串字面量(如"hello")时,编译器会将其放入字符串常量池中。当程序执行时,如果再次使用相同的字符串字面量,JVM会直接从字符串常量池中取出已存在的字符串对象,而不会创建新的对象,这样可以节省内存空间。 由于字符串Java中使用非常频繁,所以将字符串常量池放在方法区中,可以提高字符串的重用率。此外,字符串常量池的位置在方法区中也有利于GC(垃圾回收),因为当某个字符串不再被引用时,GC可以更方便地回收该字符串常量。 需要注意的是,从Java 7开始,字符串常量池被移出了PermGen空间(方法区的前身),并放置在堆中,这是因为字符串常量池中的字符串对象是可以被垃圾回收的,而且过多的字符串常量可能导致PermGen空间溢出的问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值