`
不平凡的人
  • 浏览: 35216 次
  • 性别: Icon_minigender_1
  • 来自: 嘉峪关
社区版块
存档分类
最新评论

浅析java中内存分配(一)

阅读更多

     最近,学校开始了关于操作系统方面的课程设计,刚在网上看到了一篇不错的博客关于java中的内存分配问题。参考博客简单说说java的内存分配。

     首先要知道的是Java程序运行在JVM(Java Virtual Machine,Java虚拟机)上,可以把JVM理解成Java程序和操作系统之间的桥梁(我自己觉得JVM就相当于操作系统),JVM实现了Java的平台无关性,由此可见JVM的重要性。所以在学习Java内存分配原理的时候一定要牢记这一切都是在JVM中进行的,JVM是内存分配原理的基础与前提。

1.Java程序运行的内存:

寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。

栈:保存局部变量的值,包括:1.用来保存基本数据类型的值;2.保存类的实例,即堆区对象的引用(指针);3也可以用来保存加载方法时的帧。

堆:用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量(对象的属性),并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。

 常量池:JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于堆中

代码段:用来存放从硬盘上读取的源程序代码。

数据段:用来存放static定义的静态成员。

图示:



 

2.调用过程:

(1)


 
1.JVM自动寻找main方法,执行第一句代码,创建一个Test类的实例,在栈中分配一块内存,存放一个指向堆区对象的指针110925。

2.创建一个int型的变量date,由于是基本类型,直接在栈中存放date对应的值9。

3.创建两个BirthDate类的实例d1、d2,在栈中分别存放了对应的指针指向各自的对象。他们在实例化时调用了有参数的构造方法,因此对象中有自定义初始值。

(2)



 调用test对象的change1方法,并且以date为参数。JVM读到这段代码时,检测到i是局部变量,因此会把i放在栈中,并且把date的值赋给i。

(3)



 调用change1,将1234赋给i.

(4)



 change1方法执行完毕,立即释放局部变量i所占用的栈空间。

(5)


 调用test对象的change2方法,以实例d1为参数。JVM检测到change2方法中的b参数为局部变量,立即加入到栈中,由于是引用类型的变量,所以b中保存的是d1中的指针,此时b和d1指向同一个堆中的对象。在b和d1之间传递是指针。

(6)


 change2方法中又实例化了一个BirthDate对象,并且赋给b。在内部执行过程是:在堆区new了一个对象,并且把该对象的指针保存在栈中的b对应空间,此时实例b不再指向实例d1所指向的对象,但是实例d1所指向的对象并无变化,这样无法对d1造成任何影响。

(7)



 change2方法执行完毕,立即释放局部引用变量b所占的栈空间,注意只是释放了栈空间,堆空间要等待自动回收。

(8)


调用test实例的change3方法,以实例d2为参数。同理,JVM会在栈中为局部引用变量b分配空间,并且把d2中的指针存放在b中,此时d2和b指向同一个对象。再调用实例b的setDay方法,其实就是调用d2指向的对象的setDay方法。

(9)



 调用实例b的setDay方法会影响d2,因为二者指向的是同一个对象。

(10)



 change3方法执行完毕,立即释放局部引用变量b.

3.小结:

1.分清什么是实例什么是对象。Class a= new Class();此时a叫实例,而不能说a是对象。实例在栈中,对象在堆中,操作实例实际上是通过实例的指针间接操作对象。多个实例可以指向同一个对象。

2.栈中的数据和堆中的数据销毁并不是同步的。方法一旦结束,栈中的局部变量立即销毁,但是堆中对象不一定销毁。因为可能有其他变量也指向了这个对象,直到栈中没有变量指向堆中的对象时,它才销毁,而且还不是马上销毁,要等垃圾回收扫描时才可以被销毁。

3.以上的栈、堆、代码段、数据段等等都是相对于应用程序而言的。每一个应用程序都对应唯一的一个JVM实例,每一个JVM实例都有自己的内存区域,互不影响。并且这些内存区域是所有线程共享的。这里提到的栈和堆都是整体上的概念,这些堆栈还可以细分。

4.类的成员变量在不同对象中各不相同,都有自己的存储空间(成员变量在堆中的对象中)。而类的方法却是该类的所有对象共享的,只有一套,对象使用方法的时候方法才被压入栈,方法不使用则不占用内存。

 

以上分析只涉及了栈和堆,还有一个非常重要的内存区域:常量池,这个地方往往出现一些莫名其妙的问题。常量池是干嘛的上边已经说明了,也没必要理解多么深刻,只要记住它维护了一个已加载类的常量就可以了。接下来结合一些例子说明常量池的特性。

5.Java 提供两种不同的类型:引用类型和基本类型(或内置类型)。Int是java的基本数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 

基本类型封装类 
boolean Boolean 
char Character 
byte Byte 
short Short 
int Integer 
long Long 
float Float 

double Double .

 

 

 

 

 

 

 

 

 

 

  • 大小: 3.5 KB
  • 大小: 206.7 KB
  • 大小: 204.6 KB
  • 大小: 233.8 KB
  • 大小: 219.2 KB
  • 大小: 253 KB
  • 大小: 192.4 KB
  • 大小: 252.9 KB
  • 大小: 269.6 KB
  • 大小: 285.7 KB
  • 大小: 249.1 KB
分享到:
评论

相关推荐

    Java内存分配浅析

    Java内存分配是Java编程中非常重要的概念,它涉及到程序运行时的数据存储和管理。Java程序在JVM(Java Virtual Machine,Java虚拟机)上运行,JVM作为一个平台无关的执行环境,负责Java程序的内存管理和执行。理解...

    Java中堆内存与栈内存分配浅析

    ### Java中堆内存与栈内存分配浅析 #### 一、引言 在Java编程语言中,内存管理是一项至关重要的技术。程序运行时所使用的内存主要分为两类:堆内存(Heap Memory)和栈内存(Stack Memory)。理解这两种内存类型的...

    Java内存分配全面浅析

    所以在学习Java内存分配原理的时候一定要牢记这一切都是在JVM中进行的,JVM是内存分配原理的基础与前提。l.寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。2.栈:保存局部变量的值,包括:1.用来保存基

    浅析Java抽象类和接口的比较

    Java中的抽象类(abstract class)和接口(interface)都是用于创建抽象化模型的重要工具,它们在面向对象编程中扮演着核心角色。这两种机制都允许我们定义一组方法的签名,但不提供具体实现,从而实现“设计契约”...

    浅析Java语言中对象的创建过程.pdf

    本文详细解析了Java中对象创建的整个流程,涵盖了类信息存储、对象引用、对象实体的内存分配以及实例化过程中方法的调用。 首先,Java的内存结构是理解对象创建的基础。JVM(Java虚拟机)为每一个运行中的Java应用...

    浅析Java引用类型和方法参数传递

    ### 浅析Java引用类型和方法参数传递 #### 一、引言 在Java编程语言中,理解数据类型的处理方式对于编写高效、可维护的代码至关重要。本文将深入探讨Java中的引用类型及其如何影响方法参数的传递机制。通过具体实例...

    浅析java之对象数组.pdf

    "浅析java之对象数组" 本文主要探讨Java中对象数组的知识点,着重介绍基本数据类型数组和对象数组的声明、创建和使用。文章首先介绍了Java的基本概念和特点,然后详细探讨了一维数组的声明和使用,包括基本数据类型...

    浅析Java语言中对象的创建过程.zip

    在Java编程语言中,对象的创建是程序运行的基础,它涉及到类的实例化、内存分配以及构造函数的调用等多个步骤。本篇文章将深入探讨Java中对象创建的全过程,帮助开发者理解这一核心概念。 首先,我们需要了解的是...

    浅析JAVA之垃圾回收机制.doc

    Java对象的内存分配在堆上,而C/C++中的动态内存管理通常涉及栈和堆。在Java中,创建对象时,内存分配由JVM自动完成,而C/C++则需要程序员手动使用`new`或`malloc`等关键字。Java的内存管理更为自动化,但牺牲了对...

    应用源码之防止内存溢出浅析.zip

    1. **Java内存模型**:Java内存分为堆内存和栈内存,对象分配在堆中,局部变量存储在栈上。Android应用基于Dalvik/ART虚拟机,其内存管理机制与标准Java有所不同。 2. **Android内存结构**:Android系统有Dalvik堆...

    Android防止内存溢出浅析.zip

    - **Android Studio Profiler**:提供实时内存监控,可以查看内存分配、内存泄漏检测等功能。 - **MAT (Memory Analyzer Tool)**:Eclipse插件,用于分析Hprof文件,找出内存泄漏。 - **LeakCanary**:自动检测...

    防止内存溢出浅析

    6. **使用内存分析工具**:Android Studio提供了强大的内存分析工具,如Memory Profiler,可以帮助开发者检测内存泄漏、分析内存分配和GC行为。通过这些工具,可以定位并修复内存问题。 7. **优化代码结构**:良好...

    安卓Android源码——防止内存溢出浅析.zip

    Android系统使用Java虚拟机(Dalvik或ART)进行内存分配和管理,但如果不妥善处理,很容易引发内存溢出问题,导致应用崩溃或者性能下降。本资料"安卓Android源码——防止内存溢出浅析"将深入探讨如何在Android源码...

    浅析计算机软件JAVA编程的特点及应用.pdf

    例如,Java的自动内存管理机制减少了程序员管理内存分配和回收的负担,提高了开发效率,同时降低了程序出错的可能性。 Java语言的扩展性强,是指它在运行时能够动态地加载类,这意味着程序可以在运行时扩展自己的...

    浅析Java中的 new 关键字

    1. 分配内存:Java虚拟机(JVM)在堆内存中为新对象分配所需的空间。这个过程包括为对象的所有字段分配内存。 2. 初始化:接下来,对对象的成员变量进行默认初始化。例如,基本类型变量会被赋予默认值,引用类型...

Global site tag (gtag.js) - Google Analytics