`

从JVM类加载的角度分析new String("")问题

    博客分类:
  • java
 
阅读更多

回来写博客了,还好,没有失言。

 

先告诉一下读者,也许我也还没能够说的够明白,因为这个问题,真的,还是很复杂的;所以没那份完整的自信。

 

回归主题。

 

先来说一下JVM中内存的几个概念。(在上一篇博文中有同学让我加点图,这里特意找来一个class文件结构图,自己画图,总是不会用画笔,哎!)



 

 

方法区(Method Area),虚拟机栈(VM Stack),堆(Heap),本地方法栈(Native Method Stack),程序计数器。

 

那么在这里,就主要介绍一下:VM Stack与Heap。

VM Stack主要存放的是局部变量表部分,而局部变量表存放了编译期可知的各种基本类型数据(boolean,byte,char,short,int,float,long,double),对象引用(reference类型)和returnAddress类型(指向字节码指令的地址)。

Heap主要存放的就是对象实例。

 

先来用个简单的而复杂的例子说明一下:

Object obj = new Object();

 

看看这段代码

 

 

以上代码是通过javap命令反编译出的class代码,而代码就是:

public class obj {

    Object obj = new Object();

}

 

完整命令:javap -verbose obj。(当然要先通过javac obj.java先编辑一下,再反哦)

 

再来分析一下上面的代码:

{ 
java.lang.Object obj; 

public obj(); 
Code: 
Stack=3, Locals=1, Args_size=1 
0: aload_0   
1: invokespecial #1; //Method java/lang/Object."<init>":()V 
4: aload_0 
5: new #2; //class java/lang/Object 
8: dup 
9: invokespecial #1; //Method java/lang/Object."<init>":()V 
12: putfield #3; //Field obj:Ljava/lang/Object; 
15: return 
LineNumberTable: 
line 1: 0 
line 12: 4 
} 


 

 

首先:

 Stack=3, Locals=1, Args_size=1  其中Stack为栈编号,Locals为本地变量个数,Args_size参数个数。

aload_0:将指定的引用类型本地变量推送至栈顶

invokespecial:调用超类构造方法实例初始化

putfield:为指定的类的实例域赋值

dup:复制栈顶数值并将复制值压入栈顶

new:创建一个对象,并将其引用值压入栈顶

 

在这面的过程中,首先是在栈中本地变量表中创建一个reference类型数据,再在堆中创建一个Object的实例对象,而对象类型等信息保存到方法区。

 

再回到标题说的

String a = new String("abc");(当然这样写代码是错误的

可能大家都知道String做为了一个类实现,那么new一个实例时,就在堆中创建一个实例对象,而“abc”也是保存在这块内存中,与String b = "abc";中的值"abc"存放的地址是不一样的。而a==b比较的是两个地址的值。当然在new String("abc")的时候,abc会放入到共享池中,不过与a引用的地址已经不是一样了。

比如:

package test;

public class String1 {
	st a = new st(1);
	st b = new st(1);

	public static void main(String args[]) {
		String1 cfb = new String1();
		
		if(cfb.a  == cfb.b){
			System.out.println("地址相等,你会相信吗?");
		} else{
			System.out.println("地址不相等.");
		}

	}
	class st {
		int b;
		public st(int b){
			this.b = b;
		}
	}
}

 

最后肯定是输出不相等了。

 

 

 

最后,总结一下上面所说的,还是有些混,没有写的很清楚的感觉,也许这就是我对JVM的理解还不深的原因是,应该把类加载的过程说的更清楚。

 

最后给一个我看的博文地址:

从“关于Java堆与栈的思考”一帖看错误信息的传播 作者:ZangXT

 

 

 

 

 

 

 

  • 大小: 116.8 KB
4
1
分享到:
评论
3 楼 ciding 2011-12-17  
还有一点,应该也要说一下。

就是上面的栈存储的内容。

等我把深入理解java虚拟机给学好了,再来补写吧,现在水平还没到那个层次。
2 楼 ciding 2011-12-17  
jyjava 写道
无聊的问题

是啊,问题有点无聊,都已经让别人写过了,我还在写,还有可能写的不正确。

1 楼 jyjava 2011-12-16  
无聊的问题

相关推荐

    jvm 加载class文件

    #### 二、JVM加载Class文件的过程分析 在深入探讨之前,我们首先了解Java类加载器(ClassLoader)的基本概念。Java类加载器是JVM的重要组成部分之一,它负责查找并加载类文件到JVM的内存空间中。Java程序的运行依赖...

    深入Java虚拟机JVM类加载学习笔记

    理解类加载器的工作原理对于深入掌握JVM以及解决实际开发中的问题至关重要。 **1.1 类加载器分类** 类加载器可以分为以下几种类型: - **启动类加载器(Bootstrap ClassLoader)**:这是系统级别的类加载器,负责...

    JVM加载class文件的原理机制.pdf

    JVM加载class文件的原理机制 JVM加载class文件的原理机制是Java虚拟机中一个非常重要的组件,负责将class文件加载到内存中,以便Java程序的执行。下面是JVM加载class文件的原理机制的详细介绍: 类加载的原理 在...

    自定义类加载器

    在Java编程语言中,类加载器(ClassLoader)是运行时环境的一个重要组成部分,它负责将类的字节码从各种来源加载到Java虚拟机(JVM)中,从而使得程序可以执行。自定义类加载器允许开发人员根据特定需求定制加载类的...

    Java类加载器.pdf

    Java类加载器是Java运行时环境的一个关键组成部分,负责将类文件(.class)从各种来源加载到JVM中。它不仅管理类的生命周期,还确保了类的正确加载和初始化,是Java动态特性的基石。 #### 类加载器的工作原理 Java...

    java类加载机制原理与实现

    1. 加载(Loading):在硬盘上查找并通过 IO 读入字节码文件,使用到类时才会加载,例如调用类的 main() 方法,new 对象等等。在加载阶段会在内存中生成一个代表这个类的 java.lang.Class 对象。 2. 验证...

    java 类加载器 加密

    Java 类加载器是Java运行时环境的一个重要组成部分,它的主要职责是将编译后的字节码(.class文件)加载到JVM中,使得程序能够运行。类加载器的机制保证了类的唯一性,同时也提供了灵活性,允许我们自定义加载逻辑。...

    【JDK】分析 String str=““ 与 new String()(csdn)————程序.pdf

    本文主要分析两种创建String对象的方式:`String str = ""` 和 `new String()`,并探讨它们之间的区别以及涉及的内存管理机制。 首先,我们要了解Java内存模型的基础概念。在Java中,内存分为两大部分:栈内存...

    深入理解Java中的类加载器.pdf

    Java中的类加载器机制是JVM的重要组成部分,它不仅实现了类的动态加载,还提供了强大的类隔离能力。通过深入理解类加载器的工作原理,开发者可以更好地设计和优化Java应用程序。此外,自定义类加载器也为解决特定...

    2 类加载子系统.md,学习代码

    总结,Java类加载子系统是JVM实现动态加载和运行的基础,理解其工作原理对于优化程序性能、解决加载问题以及实现特殊功能(如热部署)具有重要意义。通过深入学习和实践,开发者能够更好地掌握Java平台的运行机制,...

    JVM面试题1

    ### JVM内存结构与类加载机制详解 #### 一、JVM内存结构 JVM(Java Virtual ...通过上述步骤,我们可以理解JVM如何处理`new`指令,以及类是如何在JVM中加载和使用的。这对于深入理解Java应用程序的行为至关重要。

    Java 动态加载jar文件示例

    默认情况下,Java虚拟机(JVM)提供了三个内置的类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。它们按照层次结构工作,...

    深入java虚拟机(八)开发自己的类加载器 1

    通常,Java应用程序使用系统默认的类加载器已经能满足大部分需求,但在特定场景下,如动态加载类、加密类文件或从网络加载类等,开发者可能需要自定义类加载器。本篇文章将介绍如何开发自己的类加载器。 类加载器的...

    java自定义类加载classloader文档,包括代码

    1. **Bootstrap Class Loader(启动类加载器)**:该类加载器使用C++编写,是JVM自身的一部分,用于加载位于`JAVA_HOME/jre/lib/rt.jar`中的类库,以及其他一些核心类库(如`java.lang.*`等)。Bootstrap Class ...

    33_反射(类加载、反射)_讲义

    类加载是Java应用程序启动时的关键过程,它将.class文件从磁盘加载到内存中,使得Java虚拟机(JVM)能够执行其中的代码。本讲义将深入探讨这两个概念,以及它们在实际开发中的应用。 ### 类加载 类加载是Java程序...

    JVM面试.docx

    - 一旦主类被加载,JVM就会找到`public static void main(String[] args)`方法并开始执行。 3. **对象创建与初始化**: - 如遇到`new`关键字创建对象,JVM会在堆中为其分配内存,并调用相应的构造函数进行初始化...

    使用Java类加载和类路径实现一个简单的在线购物网站.txt

    在这个示例中,`ShoppingCart`类是通过类加载器加载到JVM中的。类加载器可以是系统默认的加载器或者自定义的类加载器。类加载器负责查找和加载类文件。 #### 类路径管理 类路径(Class Path)是指JVM查找类文件的...

    Java类动态加载(一)——java源文件动态编译为class文件

    这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时将Java源代码(.java)编译成对应的字节码文件(.class),并将其加载到Java虚拟机(JVM)中。以下是对这个主题的详细解析...

Global site tag (gtag.js) - Google Analytics