进程简略介绍:
计算机对于内存的分配是以进程为单位的,每个进程在逻辑上是隔离的,每个进程都认为自己是这台电脑上的唯一程序,自己面对所有的内存空间,(如,你的电脑有2G内存,那么一个进程认为自己可以申请到2G的内存空间)这种技术叫做进程隔离技术,保证了系统不会因为一个进程的失败,导致系统崩溃。一个进程可以向操作系统申请内存,(操作系统是系统资源的调度者,进程要使用资源必须向操作系统打报告)进程申请到的内存一般以两种形式使用,一种是栈(stack)的形式,另一种是堆(heap)的形式。一个进程可以有多个栈,但只有一个堆。一个栈对应一个线程(thread),一个进程至少需要一个线程,即至少有一个栈。
现在有一个student类,如下
class student{
String name;
int age;
void gotoSchool(){
System.out.print("Let's go to school !");
}
void eat(){
System.out.print("Let's go to eat !");
}
}
现在来创建一个学生对象 Student stu = new Student();
该语句实际是Student stu = new Student student()的缩写版,只是人们发现那样写很累,于是就把两个student合二为一了。
下面分析一下该语句是如何执行的。 进程申请到内存空间,按照两种方式分配,有的内存分配给栈,有的分配给堆。栈空间比较狭小,有大小限制,堆空间可以很大,大到和内存的容量一致。编译器是从左到右进行编译的,程序也是如此执行。
首先是碰到Student这样一个符号(token),系统会马上看下Student是什么东西,不久它发现那是一个类,然后把整个类的代码加载(class loading)到内存中。程序的代码必须从磁盘上加载到内存中才能执行,其实cpu只跟内存打交道。只是因为一断电什么都没了,所以后面才发明了硬盘,软盘等。在堆中有一个代码区(code area),用来存放Student类的代码。因为栈的空间狭小,而类代码可能很大,所以要把类代码加载到堆中。
然后,遇到stu符号,即创建一个引用变量(或句柄),其数据类型是Student,因为Student类已经加载了,所以系统也知道了stu是什么东西。因为引用变量指向一个地址(说白了就是保存地址的变量而已,相当于C语言中的指针),所占空间不大,所以把其创建在栈中即可。
接着从=右边开始,先读到new Student,即创建一个裸对象(naked object),或者说空白对象。因为类对象可能很大(如继承),所以应创建在堆中。这个裸对象主要保存自己的属性,代码区中的代码只是指导如何去做,而真正申请内存空间是在对象中。每个对象都有一个隐藏属性,叫做代码指针,指向对象所处的类,每个对象只要保存自己个性化的特征就行了,这样可以减少内存的开销,。方法可以共用,而属性不可以,才能体现出个性化。就像你不想和别人共用一个名字一样,但行为可以是一致的,可以一起上学、一起吃饭。每个对象还有另一个隐藏属性,this指针,保存了本对象在内存中的位置(俗称为指向自己)。
ps:一个对象的大小只跟属性的多少有关,而和代码的数量无关。属性是主人,方法是仆人,为属性服务。一个裸对象通过初始化,使其内部的空白对象属性获得对应,体现出个性化,然后才能进入正式使用。就像人一样,有名字、年龄、要上学等,从婴儿到成人,其初 始化是一个漫长的过程。
再接着遇到student ( ),这是一个构造方法(constructor),调用该方法为空白对象提供初始化服务。
ps:构造方法地位重要,所以被特批能使用类名作为自己的名字,即与类同名。如果一个类没有显示书写一个构造方法,系统会自动为其添加一个,该方法是一个无参空实现的构造方法。构造方法不能有返回值,而不是没有返回值(没有即为void).
最后把创建完的对象的地址通过=赋值给stu,以后对对象的的操作,只要通引用变量stu就可以了。我们可以把stu想像成是一根套住对象的绳子,绳子的数据类型决定了该绳子能套住什么样的对象。通过绳子对对象发号施令(就如我们用遥控器[引用]去操控电视机[对象]一样),对象收到命令后会访问其的代码指针,找到代码区中相应的代码并执行,人只能和栈打交道,而栈再和堆打交道。
至此语句Student stu = new Student( )就执行完了,接下去就是使用stu工作了。
ps:附件是对象创建内存布局图。
- 大小: 86.1 KB
分享到:
相关推荐
理解对象内存布局有助于优化程序性能,例如减少对象创建、理解和使用对象池,或者通过调整JVM参数来改善垃圾回收效率。`SizeOfAgent.java`、`Rule1.java`和`Rule2.java`可能包含了用于分析对象大小的代码,而`rule1....
总结来说,类对象的创建及内存解析是Java编程的基础,理解这些概念对于编写高效、无错误的代码至关重要。通过掌握对象实例化、内存分配、垃圾收集以及类和数组的特殊性,开发者可以更好地管理和优化程序的内存使用,...
总的来说,理解Java对象的创建、内存分配和JVM的工作机制对于编写高效、健壮的Java代码至关重要。这涉及到堆内存管理、对象生命周期、垃圾收集以及各种JVM优化策略。开发者应时刻关注这些细节,以便在解决性能问题时...
本文通过对Java虚拟机内存区域的分析,详细介绍了对象创建的过程,包括定义对象变量、为对象分配内存以及初始化对象等关键步骤。此外,还探讨了对象在内存中的具体布局以及初始化过程中的一些细节。希望本文能够帮助...
在Java编程语言中,计算一个对象的大小是一个相对复杂的过程,因为对象的内存布局涉及到多个因素,包括对象头、实例字段、对齐填充等。这个主题通常与性能优化和内存管理有关,尤其是在处理大规模数据结构时。这篇...
下面我们将详细分析Java对象的创建、内存布局、访问定位相关概念、原理、操作技巧与注意事项。 一、类加载检查 在JVM遇到一条new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查...
总结,Java对象的实例化内存布局涉及到对象头、实例数据和对齐填充,而访问定位则涉及到直接指针访问和解析偏移量访问。了解这些细节对于优化代码性能、理解垃圾收集机制以及编写高效并发程序至关重要。通过实际编程...
总之,Java对象和数组的内存占用取决于JVM的配置、对象的字段、数组的元素类型和长度等因素。开启或关闭压缩选项会影响对象和数组引用的大小,进而影响整体的内存占用。对于内存优化和性能调优来说,了解这些细节至...
总结来说,Java内存模型定义了对象的内存布局以及在多线程环境中对共享变量访问的规则,它为Java程序员提供了一个高级的内存模型来保证内存的有序性和一致性。理解和应用Java内存模型是编写高效且稳定Java程序的关键...
3. **堆内存**:Java对象的主要存储区域,所有实例对象和数组都存储在堆中。堆内存是线程共享的,通过垃圾收集器进行自动内存管理。Java的新生代、老年代和永久代(JDK 8前)都是堆的一部分,它们各自有不同的垃圾...
当一个Java对象被创建时,它会占用内存空间,这个空间包括对象头、实例数据和对齐填充三部分。 1. **对象头**:对象头包含了对象的元数据,如对象的类型信息、哈希码、GC分代年龄等。在HotSpot JVM中,对象头分为两...
- **内存优化**:了解对象大小有助于避免过度的对象创建,减少内存碎片,从而提高应用程序的性能。 - **垃圾收集**:对象大小影响垃圾收集的效率,小对象容易被压缩,大对象可能直接进入老年代。 - **设计模式...
此外,JNI还能获取Java对象的指针,通过`GetObjectRefType`和`GetRawPointer`等方法进行内存地址转换。 3. **JVM内部机制** JVM自身在运行时进行内存地址转换,如栈上分配、对象布局、垃圾回收等。例如,栈上分配...
Java虚拟机(JVM)在创建和管理对象时涉及多个关键概念和技术,这些概念与对象的内存布局、对象头、对象锁以及`synchronized`关键字的底层实现密切相关。在JVM中,对象的创建过程分为几个步骤: 1. **类加载检查**:...
4. **Java对象的内存布局**:在HotSpot JVM中,对于非数组对象,对象头紧接着是实例数据;对于数组,数组长度信息会放在对象头内,然后是实例数据,数组元素依次排列。 5. **内存区域**:JVM除了堆之外,还有其他几...
本章节将通过《JAVA 内存视图与封装》这一课件,详细介绍Java程序在运行时内存布局的基本概念及其重要性。 #### 二、对象的内存视图 对象的内存视图是指在程序运行过程中,对象实例在计算机内存中的具体表现形式。...
堆内存是Java对象的主要存储区域,而栈内存主要用于存储方法的局部变量。方法区存储类的信息,如类名、方法信息等。程序计数器记录了当前线程执行的指令地址,本地方法栈则服务于Java的本地方法接口。 接着,我们...
在深入了解Java内存区域的同时,我们还需要关注Java对象在内存中的布局和访问方式。 ##### 2.1 对象的创建 对象创建时,首先会在内存中为其分配空间,然后初始化对象的状态。对象的空间分配通常在Java堆中进行,但...
首先,我们要知道所有Java对象都是在堆内存(Heap)中创建的,这是Java虚拟机(JVM)为对象分配内存的地方。当我们声明一个类的实例时,JVM会为这个实例分配一块连续的内存空间。 1. 对象头(Header):每个Java...
在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知给由recipient参数确定的e-...