发布于 2017-12-18 19:26:06 | 17 次阅读 | 评论: 0 | 来源: 网友投递

这里有新鲜出炉的Java并发编程示例,程序狗速度看过来!

Java程序设计语言

java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。


本文主要介绍了Java的内存机制的相关知识,具有很好的参考价值,下面跟着小编一起来看下吧

Java把内存分为两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行以后,变量a会自动被销毁。分配给它的内存会被回收),Java会自动释放掉为该变量分配的内存空间,该内存空间可以立即另做他用。

堆内存用来存放由new创建的内存数组,在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。在堆中产生一个数组或对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就变成了数组或对象的引用变量,以后就可以在程序中使用栈中的变量来访问堆中的数组或者对象,引用变量就相当于为数组或者对象起的一个名字。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其他作用域之外后边释放。而数组和对象本省在堆中分配,即使程序运行到使用new产生的数组或者对象的语句所在的代码块之外,数组和对象本省占据的内存不会被释放。数组和对象在没有引用变量指向它的时候,才变为垃圾,不能再被使用,在随后的一个不确定时间被垃圾回收器收走(释放掉)。这也是Java比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针。

代码实例Demo1:单个对象创建


class Person {
 String name ;
 int age ;
 public void tell() {
  System.out.println("姓名:"+name+",年龄:"+age);
 }
}
public class Demo1 {
 public static void main(String[] args) {
  Person per = new Person() ;
 }
}

在上述程序中实例化了一个对象per,在实例化的过程中需要再内存中开辟空间,这其中就包括栈内存和堆内存,具体的内存分配如下图所示:

 图1-1 对象的实例化过程

我们可以从上图中发现,对象名称per被保存在了栈内存中(更加准确的说法是,在栈内存中保存的是堆内存空间的访问地址),而对象的具体内容,比如属性name和age,被保存在堆内存中。因为per对象只是被实例化,还没有被具体赋值,所以都是默认值。字符串的默认值为null,int的类型的默认值为0。前面已经提到,堆内存空间必须使用new关键字才能开辟。

代码实例Demo2:多个对象创建


class Person {
 String name ;
 int age ;
 public void tell() {
  System.out.println("姓名:"+name+",年龄:"+age);
 }
}
public class Demo2 {
 public static void main(String[] args) {
  Person per1 = new Person() ;
  Person per2 = new Person() ;
  per1.name="张三" ;
  per1.age=30 ;
  per2.age=33 ;
  per1.tell(); 
  per2.tell(); 
 }
}

图1-2 实例化两个对象

关键概念:类跟数组一样,都是属于引用类型,引用类型就是指同一个堆内存可以被多个栈内存指向,下面来看一下引用传递的简单实例。

代码实例Demo3:对象引用传递1


class Person {
 String name ;
 int age ;
 public void tell() {
  System.out.println("姓名:"+name+",年龄:"+age);
 }
}
public class Demo3 {
 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(); 
 }
}

程序运行结果为:

从程序的运行结果可以发现,两个对象输出的内容一样,实际上所谓的引用传递,就是将一个堆内存空间的使用权交给多个栈内存空间,每个栈内存空间都可以修改堆内存空间的内容,此程序的内存分配图如下所示:

图1-3 对象引用的传递内存分配

 

图1-3 对象引用的传递内存分配(续)

注意:上述实例中对象per2没有堆内存空间,这是因为对象per2只进行声明操作,也没有进行实例化操作。只是使用new关键字,实例化以后才会有堆内存空间

代码实例Demo4:对象引用传递2


 class Person {
 String name ;
 int age ;
 public void tell() {
  System.out.println("姓名:"+name+",年龄:"+age);
 }
}
public class Demo4 {
 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(); 
 }
}

上述运行程序结果为:

从程序的输出结果可以发现跟Demo3差不多。不过内存分配发生了一些变化,具体如下所示:

图1-4 (垃圾对象)的产生

注意点:

1.Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期释放不用的内存空间,只要对象不用了,就会等待GC释放空间,如上面堆内存中的name="李四";age=33。

2.一个栈内存只能指向一个堆内存空间,如果要想指向其他堆内存空间,则必须先断开已有的指向,才能分配新的指向。

Java中常见的内存区域

在Java中主要存在4块内存空间,这些内存的名称及作用如下:

  1.栈内存空间:保存所有对象的名称。

  2.堆内存空间:保存每个对象的具体属性内容。

  3.全局数据区:保存static类型的属性值。

  4.全局代码区:保存所有的方法定义。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持PHPERZ!



相关阅读 :
Java的内存机制详解
Java中的反射机制详解
JVM内存管理之JAVA语言的内存管理详解
JVM内存管理之JAVA语言的内存管理详解
Java动态代理机制详解_动力节点Java学院整理
Java 垃圾回收机制详解(动力节点Java学院整理)
Java并发控制机制详解
基于Java内存溢出的解决方法详解
Java面向对象编程中final关键字的使用方法详解
Java的MyBatis框架中关键的XML字段映射的配置参数详解
Java中静态类型检查是如何进行的实例思路详解
Java线程间的通信方式详解
最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务