`

从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  
无聊的问题

相关推荐

    Java虚拟机类加载机制?案例分析

    在《Java虚拟机类加载机制》一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的后留了一个悬念给各位,这里来揭开这个悬念。建议先看完《Java虚拟机类加载机制》这篇再来看这个,印象会比较深刻...

    java8rt.jar源码-fwh-JVM:对于JVM情况

    当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把主类加载到JVM。 public class Math { public static final int initData = 666; public static User user = new User(); public int ...

    JVM 知识点整理:对象的创建过程

    JVM 知识点整理:对象的创建过程类加载分配内存分配方式一:指针碰撞分配方式二:空闲列表如何选择?线程安全问题CAS + 失败重试方法线程本地分配缓存区(TLAB)后续工作 类加载 虚拟机遇到一条 new 指令时,首先...

    涵盖了90%以上的面试题

    JVM加载class文件的原理 双亲委派模型 为什么要自定义类加载器 如何自定义类加载器 什么是GC 内存泄漏和内存溢出 Java的内存模型(JVM的内存划分) JVM内存模型1.7和1.8的区别 如何判断一个对象是否是垃圾对象 垃圾...

    java 面试题 总结

    对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以...

    计算机(专升本)Java程序设计复习资料.doc

    A.abstract只能用来派生类,不能创建abstract类的对象 B.final修饰的类不能用来派生子类 C.abstract可与final同时修饰一个类 D.abstract方法必须在abstract类中声明,但abstract类定义中可以没有abstract方法 6....

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【JVM】双亲委派模型中,从顶层到底层,都是哪些类加载器,分别加载哪些类? 55 【JVM】能不能自己写个类叫java.lang.System? 57 【JVM】类的加载过程 58 【JVM】类的初始化 58 类什么时候才被初始化: 58 类的初始...

    day021-反射和注解笔记和代码.rar

    loader:可以指定一个类加载器加载字节码文件 2. 全限定类名.class 3. 对象名.getClass() Class类中方法newInstance():创建当前字节码对象(只能调用无参且是public修饰的构造...

    JAVA面试题最全集

    描述一下JVM加载class文件的原理机制? 41.试举例说明一个典型的垃圾回收算法? 42.请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来. 43.请写一个java程序实现线程连接池功能? 44...

    Java 高级特性.doc

    @Retention(RetentionPolicy.RUNTIME) //在运行是加载Annotation到JVM中 public @interface MyAnnotation { public String value() default "yellow"; public int[] array() default {1,2}; public Meta...

    java面试宝典2012版.pdf

    75、描述一下JVM加载class文件的原理机制? 76、heap和stack有什么区别。 77、GC是什么? 为什么要有GC? 78、垃圾回收的优点和原理。并考虑2种回收机制。 79、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收...

    Java内存分配分析/栈内存、堆内存

    首先学习JVM相关需要需要内存的组成。  基本内容  · 堆  java动态创建对象,即对于new的一个实例对象。但是需要注意的是该实例对象的...  即JVM为每个已加载的类型开辟一块区域,包括基本类型和String类型(其

    千方百计笔试题大全

    39、String s=new String(“xyz”);创建了几个String Object? 12 40、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)? 12 41、Java 的接口和C++的虚类的相同和不同...

    java面试宝典

    39、String s=new String(“xyz”);创建了几个String Object? 12 40、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)? 12 41、Java 的接口和C++的虚类的相同和不同...

    超级有影响力霸气的Java面试题大全文档

    30、String s = new String("xyz");创建了几个String Object? 两个 31、EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的?  SessionBean: Stateless Session Bean 的生命周期是由容器...

    Java学习题答案

    知识很简单, 但从面试的角度看,被试者不仅要能知道它们的区别,而且要能比较准确地表达出来(以 后写文档要能让别人看得懂,不产生歧义),回答"jsp编译后就是servlet"视为错误,回答 "jsp用于视图,servlet用于...

    最新Java面试宝典pdf版

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    java面试题

    答:运行时异常时(JVM)java虚拟机在运行过程中发生的问题,比如:内存溢出等问题。这类异常没法要求程序员去一一捕获并抛出,一般异常是Java类库或程序员自己写的代码发生的错误,这类异常可以由我们去一一捕获并...

    java基础题 很全面

    42. 描述一下JVM加载class文件的原理机制? 12 43. char型变量中能不能存贮一个中文汉字?为什么? 12 44. 多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么? 12 45. 线程的基本概念、线程的基本状态以及...

    Java面试笔试资料大全

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

Global site tag (gtag.js) - Google Analytics