`
tify
  • 浏览: 14434 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

JAVA内存管理

阅读更多

JAVA内存管理

2012-07-31 02:42:49|分类:JAVA学习笔记|举报|字号订阅

首先我们要明白一点,我们所使用的变量就是一块一块的内存空间!!

一、内存管理原理:

在java中,有java程序、虚拟机、操作系统三个层次,其中java程序与虚拟机交互,而虚拟机与操作系统间交互!这就保证了java程序的平台无关性!下面我们从程序运行前,程序运行中、程序运行内存溢出三个阶段来说一下内存管理原理!

1、程序运行前:JVM向操作系统请求一定的内存空间,称为初始内存空间!程序执行过程中所需的内存都是由java虚拟机从这片内存空间中划分的。

2、程序运行中:java程序一直向java虚拟机申请内存,当程序所需要的内存空间超出初始内存空间时,java虚拟机会再次向操作系统申请更多的内存供程序使用!

3、内存溢出:程序接着运行,当java虚拟机已申请的内存达到了规定的最大内存空间,但程序还需要更多的内存,这时会出现内存溢出的错误!

<wbr></wbr>
至此可以看出,Java 程序所使用的内存是由 Java 虚拟机进行管理、分配的。Java 虚拟机规定了 Java 程序的初始内存空间和最大内存空间,开发者只需要关心 Java 虚拟机是如何管理内存空间的,而不用关心某一种操作系统是如何管理内存的。
二、RUNTIME 类的使用:

Java 给我们提供了Runtime 类得到JVM 内存的信息
方法名称 参数 作用 返回值
getRuntime 获取Runtime 对象 Runtime 对象
totalMemory 获取JVM 分配给程序的内存数量 long:内存数量
freeMemory 获取当前可用的内存数量 long:内存数量
maxMemory 获取JVM 可以申请到的最大内存数量 long:内存数量

三、内存空间逻辑划分:

JVM 会把申请的内存从逻辑上划分为三个区域,即:方法区、堆与栈。

方法区:方法区默认最大容量为64M,Java虚拟机会将加载的java类存入方法区,保存类的结构(属性与方法),类静态成员等内容。

堆:默认最大容量为64M,堆存放对象持有的数据,同时保持对原类的引用。可以简单的理解为对象属性的值保存在堆中,对象调用的方法保存在方法区。

栈:栈默认最大容量为1M,在程序运行时,每当遇到方法调用时,Java虚拟机就会在栈中划分一块内存称为栈帧(Stack frame),栈帧中的内存供局部变量(包括基本类型与引用类型)使用,当方法调用结束后,Java虚拟机会收回此栈帧占用的内存。

四、java数据类型

JAVA内存管理 - 小白 - 小白的博客


1、基本数据类型:没封装指针的变量。
声明此类型变量,只会在栈中分配一块内存空间。

2、引用类型:就是底层封装指针的数据类型。
他们在内存中分配两块空间,第一块内存分配在栈中,只存放别的内存地址,不存放具体数值,我们也把它叫指针类型的变量,第二块内存分配在堆中,存放的是具体数值,如对象属性值等。

3、下面我们从一个例子来看一看:
public class Student {
String stuId;
String stuName;
int stuAge;
}

public class TestStudent {
public static void main(String[] args) {
Student zhouxingxing = new Student();
String name = new String("旺旺");
int a = 10;
char b = 'm';
zhouxingxing.stuId = "9527";
zhouxingxing.stuName = "周星星";
zhouxingxing.stuAge = 25;
}
}

(1)类当然是存放在方法区里面的。

(2)Student zhouxingxing = new Student();
这行代码就创建了两块内存空间,第一个在栈中,名字叫zhouxingxing,它就相当于指针类型的变量,我们看到它并不存放学生的姓名、年龄等具体的数值,而是存放堆中第二块内存的地址,第二块才存放具体的数值,如学生的编号、姓名、年龄等信息。

(3)int a = 10;
这是基本数据类型变量,具体的值就存放在栈中,并没有只指针的概念!

下图就是本例的内存布置图:
JAVA内存管理 - 小白 - 小白的博客

此外我们还要知道Student zhouxingxing = new Student(); 包括了声明和创建,即:Student zhouxingxing;和zhouxingxing = new Student();其中声明只是在栈中声明一个空间,但还没有具体的值,声明后的情况如下图所示:
JAVA内存管理 - 小白 - 小白的博客
创建后的情况如下图所示:

JAVA内存管理 - 小白 - 小白的博客

(4)引用类型中的数组也封装了指针,即便是基本数据类型的数组也封装了指针,数组也是引用类型。比如代码int[] arr = new int[]{23,2,4,3,1};如下图所示:
JAVA内存管理 - 小白 - 小白的博客
五、java值传参与引用参数

(1)参数根据调用后的效果不同,即是否改变参数的原始数值,又可以分为两种:按值传递的参数与按引用传递的参数。
按值传递的参数原始数值不改变,按引用传递的参数原始数值改变!这是为什么呢?其实相当简单:
我们知道基本数据类型的变量存放在栈里面,变量名处存放的就是变量的值,那么当基本数据类型的变量作为参数时,传递的就是这个值,只是把变量的值传递了过去,不管对这个值如何操作,都不会改变变量的原始值。而对引用数据类型的变量来说,变量名处存放的地址,所以引用数据类型的变量作为传参时,传递的实际上是地址,对地址处的内容进行操作,当然会改变变量的值了!

(2)特例:string

public class TestString {
public static void main(String[] args) {
String name = "wangwang";
TestString testString = new TestString();
System.out.println("方法调用前:" + name);
testString.change(name);
System.out.println("方法调用后:" + name);
}
void change(String str) {
str = "旺旺老师";
System.out.println("方法体内修改值后:" + str);
}
}

结果:
方法调用前:wangwang
方法体内修改值后:旺旺老师
方法调用后:wangwang

分析:
上例中,虽然参数String 是引用数据类型,但其值没有发生改变,这是因为String 类
是final 的,它是定长,我们看初始情况,即String name = "wangwang";这行代码运行
完,如下图:
JAVA内存管理 - 小白 - 小白的博客

当调用方法时testString.change(name),内存变化为:

JAVA内存管理 - 小白 - 小白的博客


在方法体内,参数str赋予一个新值,str = "旺旺老师"。因为String是定长,系统就会在堆中分配一块新的内存空间37DF,这样str指向了新的内存空间37DF,而name还是指向36DF, 37DF的改变对它已没影响:

JAVA内存管理 - 小白 - 小白的博客

最后,方法调用结束,str与37DF的内存空间消亡。Name的值依然为wangwang,并没有改变。
所以String虽然是引用类型参数,但值依然不变:

JAVA内存管理 - 小白 - 小白的博客
(3)无法交换的例子:

public class TestChange {
void change(Student stu1, Student stu2) {
stu1.stuAge ++;
stu2.stuAge ++;
Student stu = stu1;
stu1 = stu2;
stu2 = stu;
}
public static void main(String[] args) {
Student furong = new Student();
furong.stuName = "芙蓉姐姐";
furong.stuAge = 30;
Student fengjie = new Student();
fengjie.stuName = "凤姐";
fengjie.stuAge = 26;
TestChange testChange = new TestChange();
testChange.change(furong, fengjie);
System.out.println(furong.stuName);
System.out.println(furong.stuAge);
System.out.println(fengjie.stuName);
System.out.println(fengjie.stuAge);
}
}

运行结果:
芙蓉姐姐
31
凤姐
27

分析:

JAVA内存管理 - 小白 - 小白的博客
分享到:
评论

相关推荐

    Java内存管理机制相关资料汇总

    资源名称:Java内存管理机制相关资料汇总资源目录:【】java内存回收机制及预防【】java内存管理机制【】java内存管理白皮书【】Java虚拟机内存管理_对象和引用_空指针【】深入理解java虚拟机jvm高级行与最佳实践...

    Java内存管理机制

    1、JAVA 内存管理总结 2、Java的内存管理实例 3、垃圾回收机制:

    java内存管理精彩概述

    java内存管理精彩概述 java内存管理精彩概述 java内存管理精彩概述

    java内存管理详细介绍.doc

    本文档主要讲述的是java内存管理详细介绍;对于从事C、C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又是执行最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象...

    java内存管理 .pptx

    java内存管理

    java内存管理总结

    java 内存管理 详细介绍了java内存管理各个方面的内容

    关于java内存管理的一些理解

    主要关于java虚拟机的运行时数据区域,参考了周志明的深入理解java虚拟机,还涉及到了native方法、垃圾回收机制等等。

    java内存管理白皮书-英文版

    One strength of the Java™ 2 Platform, Standard Edition (J2SE™) is that it performs automatic memory management, thereby shielding the developer from the complexity of explicit memory management.

    JAVA 内存管理总结

    JAVA 内存管理总结 1. java是如何管理内存的 2. 什么叫java的内存泄露 3. JVM的内存区域组成 4.Java中数据在内存中是如何存储的 5. Java的内存管理实例

    java内存管理以及GC

    内存管理简介 内存管理的职责为分配内存,回收内存。 没有自动内存管理的语言/平台容易发生错误。 典型的问题包括悬挂指针问题,一个指针引用了一个已经被回收的内存地址,导致程序的运行完全不可知。 另一个...

    java内存管理详细介绍

    java内存管理详细介绍,增强自己对虚拟机和内存进一步认识!

    java内存管理深入讲解

    java内存管理深入讲解 基本是理解java程序内存的直接能用的资料了

    Java的内存管理机制分析

    Java的内存管理机制分析 让你了解java的内存管理 以及如何去分析它

    java内存管理 ppt

    java内存结构,垃圾收集,并发收集,虚拟机参数

    java内存管理与垃圾回收

    java内存管理与垃圾回收

    JAVA内存管理机制

    JAVA内存管理机制的思维导图

    JAVA内存管理模式研究.pdf

    JAVA内存管理模式研究

    java内存管理

    NULL 博文链接:https://zhengzhuangjie.iteye.com/blog/1924477

Global site tag (gtag.js) - Google Analytics