1.Java的内存机制
Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销毁。分配给它的内存会被回收),Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。
堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是 Java 比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
代码实例Test01:单个对象创建
在上述程序中实例化了一个对象per,在实例化对象的过程中需要在内存中开辟空间,这其中就包括栈内存和对内存。具体的内存分配如下图所示:
我们可以从上图中发现,对象名称per被保存在了栈内存中(更加准确的说法是,在栈内存中保存的是堆内存空间的访问地址),而对象的具体内容,比如属性name和age,被保存在了堆内存中。因为per对象只是被实例化,还没有具体被赋值,所以都是默认值。字符串的默认值为null,int类型的默认值为0。前面也已经提到,堆内存空间必须使用new关键字才能开辟。
代码实例Test02:多个对象创建
关键概念:类跟数组一样,都是属于引用类型,引用类型就是指一堆对内存可以同时被多个栈内存指向。下面来看一下引用传递的简单实例。
代码实例Test03:对象引用传递1
程序运行结果为:
姓名:张三,年龄:33
姓名:张三,年龄:33
从程序的运行结果可以发现,两个对象输出的内容一样,实际上所谓的引用传递,就是将一个堆内存空间的使用权交个多个栈内存空间,每个栈内存空间都可以修改堆内存空间的内容,此程序的内存分配图如下所示:
注意:上述实例中对象per2没有堆内存空间,这是因为对象per2只进行了声明操作,也没有进行实例化操作。只有使用new关键字实例化以后才会有对内存空间。
代码实例Test04:对象引用传递2
上述程序运行结果为:
姓名:张三,年龄:30
姓名:张三,年龄:30
从程序的输出结果可以
发现可Test03一样。不过内存分配发生了一些变化,具体如下所示:
注意点:
Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期施放不用的内存空间,只要对象不用了,就会等待GC释放空间,如上面堆内存中的name="李四";age=33。
一个栈内存只能指向一个对内存空间,如果要想再指向其他的堆内存空间,则必须先断开已有的指向才能分配新的指向。
java中常用的内存区域
在java中主要存在4块内存空间,这些内存的名称及作用如下:
栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
堆内存空间:保存每个对象的具体属性内容。
全局数据区:保存static类型的属性。
全局代码区:保存所有的方法定义。
Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销毁。分配给它的内存会被回收),Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。
堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是 Java 比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
代码实例Test01:单个对象创建
class Person{ String name; int age; public void tell(){ System.out.println("姓名:"+name+"年龄"+age); } } public class Test01 { public static void main(String[] args) { Person per=new Person(); } }
在上述程序中实例化了一个对象per,在实例化对象的过程中需要在内存中开辟空间,这其中就包括栈内存和对内存。具体的内存分配如下图所示:
我们可以从上图中发现,对象名称per被保存在了栈内存中(更加准确的说法是,在栈内存中保存的是堆内存空间的访问地址),而对象的具体内容,比如属性name和age,被保存在了堆内存中。因为per对象只是被实例化,还没有具体被赋值,所以都是默认值。字符串的默认值为null,int类型的默认值为0。前面也已经提到,堆内存空间必须使用new关键字才能开辟。
代码实例Test02:多个对象创建
class Person{ String name; int age; public void tell(){ System.out.println("姓名:"+name+",年龄:"+age); } } public class Test02 { public static void main(String[] args) { Person per1=new Person(); Person per2=new Person(); per1.name="张三"; per1.age=30; per2.name="李四"; per2.age=33; per1.tell(); per2.tell(); } }
关键概念:类跟数组一样,都是属于引用类型,引用类型就是指一堆对内存可以同时被多个栈内存指向。下面来看一下引用传递的简单实例。
代码实例Test03:对象引用传递1
class Person{ String name; int age; public void tell(){ System.out.println("姓名:"+name+",年龄:"+age); } } public class Test03{ public static void main(String[] args) { Person per1=new Person(); Person per2=per1; per1.name="张三"; per1.age=30; per2.age=33; per1.tell(); per2.tell(); } }
程序运行结果为:
姓名:张三,年龄:33
姓名:张三,年龄:33
从程序的运行结果可以发现,两个对象输出的内容一样,实际上所谓的引用传递,就是将一个堆内存空间的使用权交个多个栈内存空间,每个栈内存空间都可以修改堆内存空间的内容,此程序的内存分配图如下所示:
注意:上述实例中对象per2没有堆内存空间,这是因为对象per2只进行了声明操作,也没有进行实例化操作。只有使用new关键字实例化以后才会有对内存空间。
代码实例Test04:对象引用传递2
class Person{ String name; int age; public void tell(){ System.out.println("姓名:"+name+",年龄:"+age); } } public class Test04 { public static void main(String[] args) { Person per1=new Person(); Person per2=new Person(); per1.name="张三"; per1.age=30; per2.name="李四"; per2.age=33; per2=per1; per1.tell(); per2.tell(); } }
上述程序运行结果为:
姓名:张三,年龄:30
姓名:张三,年龄:30
从程序的输出结果可以
发现可Test03一样。不过内存分配发生了一些变化,具体如下所示:
注意点:
Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期施放不用的内存空间,只要对象不用了,就会等待GC释放空间,如上面堆内存中的name="李四";age=33。
一个栈内存只能指向一个对内存空间,如果要想再指向其他的堆内存空间,则必须先断开已有的指向才能分配新的指向。
java中常用的内存区域
在java中主要存在4块内存空间,这些内存的名称及作用如下:
栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
堆内存空间:保存每个对象的具体属性内容。
全局数据区:保存static类型的属性。
全局代码区:保存所有的方法定义。
发表评论
-
List<Map> 排序
2016-08-03 11:03 940import java.util.ArrayList; im ... -
相对路径和绝对路径的区别,java获取项目访问路径的方法
2016-07-19 13:58 655相对路径和绝对路径的区别 在HTML里只要涉及文件的地方( ... -
POI 单元格
2016-07-07 11:48 488POI 单元格合并中的CellRangeAddress 参数: ... -
StringBuffer和StringBuilder的区别
2016-06-28 11:36 443StringBuffer、StringBuilder和Stri ... -
平均分割list
2016-06-26 19:22 1226private static List<List< ... -
定时任务&&找出两个list的不同
2016-06-21 13:55 367/*-------------------------appl ... -
时间类
2016-06-21 13:38 525/* * Licensed to the Apache S ... -
常用map总结
2016-06-21 09:39 420Map map = new HashMap(); I ... -
遍历listmap 遍历map
2016-04-27 16:23 545package excel; import java ... -
Criteria Query
2016-01-29 13:32 480Criteria Query通过面向对象化的设计,将数据查询条 ... -
List和ArrayList的区别
2016-01-28 09:38 523List和ArrayList的区别 List是一个接口,而Li ... -
StringUtils.isEmpty用法
2016-01-28 09:21 678StringUtils 方法的操作对象是 java.lang. ... -
java中重载与重写的区别
2016-01-27 13:50 534java中重载与重写的区别 ... -
loginfilter
2016-01-26 16:02 334dabdabdabdabdabdabdab -
web.xml
2015-11-13 13:53 3441、启动一个WEB项目的时 ... -
hashMap.js
2015-11-04 09:57 436function HashMap() { /** Map大 ... -
分页处理
2015-11-01 09:21 746select * from (SELECT rownum as ... -
前台传字符串导出word
2015-10-29 13:43 696package com.yunfengtech.common; ... -
SQL时间比较大小
2015-10-28 16:53 616public List<RBean> queryF ... -
js对象定义
2015-10-23 17:18 569一,基本概念 1,自定 ...
相关推荐
Java内存机制是Java虚拟机(JVM)的关键组成部分,它管理着程序运行时的数据存储。在Java中,内存主要分为以下几个区域: 1. **Heap(堆)**:这是Java中最主要的内存区域,用于存储所有的类实例和数组。当堆空间...
### Java内存机制学习和使用 #### 一、Java内存机制概览 Java内存管理是Java开发人员必须掌握的核心概念之一。良好的内存管理不仅能够提升应用性能,还能避免常见的内存泄漏问题。本文旨在深入探讨Java内存机制,...
java内存机制与启动参数优化 Java 内存机制是指 Java 虚拟机(JVM)管理内存的机制。JVM 主要管理两种类型的内存:堆(Heap)和非堆(Perm)。堆是 Java 代码使用的内存,留给开发人员使用的;非堆是 JVM 留给自己...
### Java内存机制、配置与监控详解 #### 一、Java内存模型 Java内存模型是Java虚拟机(JVM)管理程序运行时数据区域的核心部分,它定义了Java对象的存储方式以及线程对这些变量的访问规则。Java内存区域主要包括...
粗解java内存机制
总的来说,理解Java内存机制的堆和栈有助于编写更高效、更稳定的代码。正确地管理内存可以避免性能瓶颈和内存溢出问题,而深入理解对象创建和引用的工作方式则有助于优化程序设计,尤其是在处理大量对象或复杂数据...
Java内存机制主要包括堆内存(Heap)和栈内存(Stack)两个主要部分,它们各自具有特定的存储特点和作用。在Java编程中,理解这两者的区别和交互方式对于优化程序性能和避免内存泄漏至关重要。 栈内存主要用于存储...
Java内存机制主要包括堆内存(Heap)和栈内存(Stack)两个主要部分,它们各自具有不同的特点和作用。栈内存主要用于存储基本类型变量(如int、double等)和对象的引用,而堆内存则是用于存储由new关键字创建的对象...
简略的描述了Java的内存机制,但内容尚不完善,有密码,暂时请勿下载。内容补全后会再上传。
通过对Java内存管理机制的深入分析,我们可以了解到Java如何高效地管理和利用内存资源。理解这些机制对于优化Java应用程序的性能至关重要,特别是在处理大规模数据集或多线程环境时。此外,合理配置JVM参数和选择...
Java内存监视是优化Java应用程序性能的关键环节,尤其是在大型企业级应用中,理解...对于标签中的“Java源码-系统相关”,意味着这个工具或示例代码是与Java系统层面的操作紧密相关的,对理解Java内存机制有直接帮助。
### Java内存分配机制详解 #### 一、引言 Java作为一种广泛应用的编程语言,其内存管理机制对于确保程序高效稳定运行至关重要。本文旨在详细介绍Java内存分配机制中的几个关键概念:寄存器、栈、堆、静态域、常量...
资源名称:Java内存管理机制相关资料汇总资源目录:【】java内存回收机制及预防【】java内存管理机制【】java内存管理白皮书【】Java虚拟机内存管理_对象和引用_空指针【】深入理解java虚拟机jvm高级行与最佳实践...
Java内存模型是Java虚拟机规范中定义的一部分,它规定了Java程序中变量的读写行为,以及线程之间的交互规则。理解Java内存模型对于编写正确、高效的多线程程序至关重要。在Java 5之前,Java内存模型的描述比较模糊,...
总的来说,Java内存管理和诊断是一个复杂的过程,需要深入理解JVM的工作原理和垃圾收集机制。通过合理使用各种工具和技巧,开发者能够有效地识别和解决内存泄露和溢出问题,确保应用程序的稳定性和性能。
Java内存回收机制 Java的内存管理主要集中在堆(Heap)区域,其中对象的创建通常是通过`new`关键字或反射方式完成,而对象的释放则由Java虚拟机(JVM)通过垃圾回收(GC)机制自动处理。对象回收的基本原则是:当一个...