回来写博客了,还好,没有失言。
先告诉一下读者,也许我也还没能够说的够明白,因为这个问题,真的,还是很复杂的;所以没那份完整的自信。
回归主题。
先来说一下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的理解还不深的原因是,应该把类加载的过程说的更清楚。
最后给一个我看的博文地址:
- 大小: 116.8 KB
分享到:
相关推荐
#### 二、JVM加载Class文件的过程分析 在深入探讨之前,我们首先了解Java类加载器(ClassLoader)的基本概念。Java类加载器是JVM的重要组成部分之一,它负责查找并加载类文件到JVM的内存空间中。Java程序的运行依赖...
理解类加载器的工作原理对于深入掌握JVM以及解决实际开发中的问题至关重要。 **1.1 类加载器分类** 类加载器可以分为以下几种类型: - **启动类加载器(Bootstrap ClassLoader)**:这是系统级别的类加载器,负责...
JVM加载class文件的原理机制 JVM加载class文件的原理机制是Java虚拟机中一个非常重要的组件,负责将class文件加载到内存中,以便Java程序的执行。下面是JVM加载class文件的原理机制的详细介绍: 类加载的原理 在...
在Java编程语言中,类加载器(ClassLoader)是运行时环境的一个重要组成部分,它负责将类的字节码从各种来源加载到Java虚拟机(JVM)中,从而使得程序可以执行。自定义类加载器允许开发人员根据特定需求定制加载类的...
Java类加载器是Java运行时环境的一个关键组成部分,负责将类文件(.class)从各种来源加载到JVM中。它不仅管理类的生命周期,还确保了类的正确加载和初始化,是Java动态特性的基石。 #### 类加载器的工作原理 Java...
1. 加载(Loading):在硬盘上查找并通过 IO 读入字节码文件,使用到类时才会加载,例如调用类的 main() 方法,new 对象等等。在加载阶段会在内存中生成一个代表这个类的 java.lang.Class 对象。 2. 验证...
Java 类加载器是Java运行时环境的一个重要组成部分,它的主要职责是将编译后的字节码(.class文件)加载到JVM中,使得程序能够运行。类加载器的机制保证了类的唯一性,同时也提供了灵活性,允许我们自定义加载逻辑。...
本文主要分析两种创建String对象的方式:`String str = ""` 和 `new String()`,并探讨它们之间的区别以及涉及的内存管理机制。 首先,我们要了解Java内存模型的基础概念。在Java中,内存分为两大部分:栈内存...
Java中的类加载器机制是JVM的重要组成部分,它不仅实现了类的动态加载,还提供了强大的类隔离能力。通过深入理解类加载器的工作原理,开发者可以更好地设计和优化Java应用程序。此外,自定义类加载器也为解决特定...
总结,Java类加载子系统是JVM实现动态加载和运行的基础,理解其工作原理对于优化程序性能、解决加载问题以及实现特殊功能(如热部署)具有重要意义。通过深入学习和实践,开发者能够更好地掌握Java平台的运行机制,...
### JVM内存结构与类加载机制详解 #### 一、JVM内存结构 JVM(Java Virtual ...通过上述步骤,我们可以理解JVM如何处理`new`指令,以及类是如何在JVM中加载和使用的。这对于深入理解Java应用程序的行为至关重要。
默认情况下,Java虚拟机(JVM)提供了三个内置的类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。它们按照层次结构工作,...
通常,Java应用程序使用系统默认的类加载器已经能满足大部分需求,但在特定场景下,如动态加载类、加密类文件或从网络加载类等,开发者可能需要自定义类加载器。本篇文章将介绍如何开发自己的类加载器。 类加载器的...
1. **Bootstrap Class Loader(启动类加载器)**:该类加载器使用C++编写,是JVM自身的一部分,用于加载位于`JAVA_HOME/jre/lib/rt.jar`中的类库,以及其他一些核心类库(如`java.lang.*`等)。Bootstrap Class ...
类加载是Java应用程序启动时的关键过程,它将.class文件从磁盘加载到内存中,使得Java虚拟机(JVM)能够执行其中的代码。本讲义将深入探讨这两个概念,以及它们在实际开发中的应用。 ### 类加载 类加载是Java程序...
- 一旦主类被加载,JVM就会找到`public static void main(String[] args)`方法并开始执行。 3. **对象创建与初始化**: - 如遇到`new`关键字创建对象,JVM会在堆中为其分配内存,并调用相应的构造函数进行初始化...
在这个示例中,`ShoppingCart`类是通过类加载器加载到JVM中的。类加载器可以是系统默认的加载器或者自定义的类加载器。类加载器负责查找和加载类文件。 #### 类路径管理 类路径(Class Path)是指JVM查找类文件的...
这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时将Java源代码(.java)编译成对应的字节码文件(.class),并将其加载到Java虚拟机(JVM)中。以下是对这个主题的详细解析...