数组及其内存控制

作者:禅楼望月(http://www.cnblogs.com/yaoyinglong/

静态的Java数组

Java语言是典型的静态语言,因而,数组也是静态的,即当该数组被初始化之后,该数组的长度是不可变的。

java 语言的数组变量是引用类型,什么意思呢?意思就是,数组变量并不是数组本身,它只是指向堆内存中的数组对象。如:

这3个变量以及各自引用的数组在内存中的分配如图:

我们平时可以通过改变数组变量的指向,让它指向的堆内存中的其他数组对象(前提是他们的编译类型是兼容的),从表面上看起来好像是更改了数组的长度。但是其实我们只是让该数组变量指向了另一个数组对象,而原来的那个数组对象再没有其他数组变量指向的情况下等待垃圾回收。

对数组变量来说,它并不需要进行所谓的初始化,只是让数组变量指向一个有效的数组对象即可。

对Java程序来说,所有的引用类型的变量都不需要经过所谓的初始化,需要进行初始化的只是该引用变量所引用的对象。

所有的局部变量都是存放在栈内存中,不管其是引用类型的变量还是基本类型的变量,都是存储在各自的方法栈区中;但引用类型变量所引用的对象(包括数组、普通的Java对象)则总是存储在堆内存中。

对于Java,堆内存中的对象(不管是数组还是普通Java对象)通常不允许直接访问,为了访问堆内存中的对象,通常只能通过引用变量。

数组变量都是存储在栈内存中的,但数组元素则作为数组对象的一部分被保存在堆内存中,无论它们是基本类型的数组元素还是引用类型的数组元素。

基本类型数组的初始化

对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中,因此程序直接为数组分配内存空间,再将数组元素的值存入对应的内存里即可。

intArr只是一个数组变量,它存在它所在的方法栈区中,它实际指向对内存中的一个数组对象。所以应该将数组变量与数组对象分开。

引用类型数组的初始化

比基本类型数组初始化复杂了一点:引用类型数组元素里面存还是引用,而不是引用对象本身,它指向堆内存中另一块内存单元(这块内存中存储了引用变量所指向的对象:数组或者Java对象)。

public class Person {
    private String name;
    private int age;
    public Person(String name,int age) {
        this.name=name;
        this.age=age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public String toString(){
        return "我叫"+name+"   我的年龄是:"+age;
    }
    public static void main(String[] args) {
        Person[] students=new Person[3];
        Person xiaoming=new Person("小明", 10);
        Person xiaohong=new Person("小红", 15);
        Person xiaozhang=new Person("小张", 20);

        students[0]=xiaoming;
        students[1]=xiaohong;
        students[2]=xiaozhang;
        System.out.println(Arrays.toString(students));
        System.out.println("xiaoming和students[0]是不是指向同一个Java对象?-->"+(xiaoming==students[0]));

        xiaohong.setName("我的名字改了");
        System.out.println("通过变量xiaoming修改了它指向的Java对象的name属性:"+xiaohong.getName());

        System.out.print("获取students[1]的name属性为:");
        System.out.println(students[1].getName());
    }
}
打印出的结果为:

main函数执行过程的内存示意:

时间: 2024-10-19 08:19:58

数组及其内存控制的相关文章

Java数组与内存控制

一.Java数组初始化 Java数组是静态的,即当数组被初始化之后,该数组的长度是不可变的.Java数组使用之前必须先对数组对象进行初始化,所谓初始化,就是为数组的所有元素分配内存空间,并为每个数组元素指定初始值.(文章来源于李刚老师的<突破java程序员的16课>) 1:基本类型数组的两种初始化方式 静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度. 动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值. 不要同时使用静态初始化和动态初始化,也就是

Java细节整理——数组与内存控制

重点:使用Java数组之前,必须对数组对象进行初始化. 当数组的所有元素都被分配了合适的内存空间,并指定了初始值时,数组的初始化完成.程序以后将不能重新改变数组对象在内存中的位置和大小. 知识点整理: 1.数组的初始化有以下两种方式: 1)静态初始化:初始化时由程序员显示指定每个数组元素的初始值,由系统决定数组的长度. 2)动态初始化:初始化时程序员只指定数组的长度,由系统为数组元素分配初始值. 不管使用哪种方式初始化Java数组,一旦初始化完成,该数组的长度就不可改变. 代码示例: publi

程序员的基本功之数组与内存控制

1.数组初始化 Java的数组是静态的,既数组一旦初始化之后,该数组的长度就不可变,Java的数组需要初始化才能使用 数组的初始化就是为数组对象在堆内存中分配一段数组长度的连续的内存空间,并设定初始值(注意并不是数组变量初始化,而是数组对象) 初始化的方式有两种: 1)静态初始化:程序员显示的指定每个数组元素的初始值,并由系统决定数组的长度 2)动态初始化:初始化时只指定数组的长度,由系统为数组元素分配初始值 数组变量本身是引用类型,存储在栈内存中,而数组对象存储在堆内存中 int[] arr1

java 基础概念 -- 数组与内存控制

问题1: Java在声明数组的过程中,是怎样分配内存的? 在栈内存中 建一个数组变量,再在堆内存中 建一个 数组对象.至于详细的内存分配细节,还得看 该初始化是 数组动态初始化 还是 数组静态初始化. 问题2: Java数组的初始化方式 有哪几种? 两种:动态初始化 和 静态初始化.动态初始化 指的是 仅仅指定数组的长度,不指明每个数组的元素.  静态初始化 指的是 详细指定数组的每个元素. 问题3: Java 的基本类型数组 和 应用类型数组 之间,在初始化时的内存分配机制有什么差别? Jav

一,数组与内存控制

一,数组的初始化 1,数组初始化之后,长度不变,且数组初始化后才可以使用,所谓得初始化,就是为数组对象得元素分配内存空间,并且指定初始值. 2,初始化的两种方式:静态初始化,初始化时显式指定每个数组元素的初始值,由系统决定数组长度. 动态初始化,初始化时,只是指定数组长度,有系统为数组元素分配初始值. 3,java数组变量时引用类型变量,不是数组本身,它时只想堆内存中的数组对象. 例如: int arr[] arr=new int[]{1,2,3} 执行int arr[]之后,这是在main()

【JAVA基础教程】-浅谈数组及其内存控制

在用JAVA数据前我们都知道必须要先对数组对象进行初始化.当数组的所有元素都被分配合适的内存空间,当制定了初始值时,数组初始化完成.程序以后将不能重新改变数组对象在内存中的位置和大小.那么: 1.JAVA数组为静态,即一旦初始化后,其长度是不可改变的. 2. 数组变量是引用变量,并不是数组对象本身. 3. 两种初始化方式: 动态初始化:指定数组的长度,初始值自动生成. 静态初始化:指定初始值,长度自动生成. 4. JAVA中,引用变量本身无需初始化,引用变量所引用的对象是需要初始化的. 5. 所

【Java学习笔记之八】java二维数组及其多维数组的内存应用拓展延伸

多维数组声明 数据类型[][] 数组名称; 数据类型[] 数组名称[]; 数据类型数组名称[][]; 以上三种语法在声明二维数组时的功能是等价的.同理,声明三维数组时需要三对中括号,中括号的位置可以在数据类型的后面,也可以在数组名称的后面,其它的依次类推. 例如: int[][] map; char c[][]; 和一维数组一样,数组声明以后在内存中没有分配具体的存储空间,也没有设定数组的长度.  -------------------------------------------------

RabbitMQ 内存控制 硬盘控制

一.内存控制: vm_memory_high_watermark 该值为内存阈值,默认为0.4.意思为物理内存的40%.40%的内存并不是内存的最大的限制,它是一个发布的节制,当达到40%时Erlang会做GC.最坏的情况是使用内存80%.如果把该值配置为0,将关闭所有的publishing . rabbitmqctl set_vm_memory_high_watermark 0 Paging 内存阈值,该值为默认为0.5,该值为vm_memory_high_watermark的20%时,将把内

深入浅出NodeJS——内存控制

基于无阻塞.事件驱动建立的Node服务,具有内存消耗低的优点,非常适合处理海量的网络请求. V8的垃圾回收机制与内存限制 Javascript和Java类似,由垃圾回收机制来进行自动内存管理,而Node是构建在V8虚拟机基础上,所以其内存回收和V8运行机制息息相关. V8的内存限制:64位系统约为1.4GB.32位系统约为0.7GB process.memoryUsage(),返回值包括heapTotal代表已申请到的堆内存,heapUsed当前使用的内存,rss(resident set si