Unit03 - 对象内存管理 、 继承的意义(上)    

1.内存管理:由JVM来管理的
  1)堆:
    1.1)存储所有new出来的对象(包含成员变量)
    1.2)没有任何引用所指向的对象就是垃圾,
        垃圾回收器(GC)不定时清理垃圾,
        回收过程是透明的(看不到的),
        调用System.gc()建议GC尽快来回收
    1.3)成员变量的生命周期:
          创建对象时存在堆中,对象被回收时一并被回收
    1.4)内存泄露:不再使用的对象没有被及时的回收
                 建议:对象不再使用时及时将引用设置为null
  2)栈:
    2.1)用于存储正在调用中方法的所有局部变量(包括参数)
    2.2)调用方法时在栈中为该方法分配一块对应的栈帧,
        栈帧中存储的是方法中的所有局部变量(包括参数),
        方法调用结束时,栈帧被清除,局部变量一并被清除
    2.3)局部变量的生命周期:
          调方法时存在栈中,方法结束时与栈帧一起被清除
  3)方法区:
    3.1)用于存储.class字节码文件(包括方法)
    3.2)方法只有一份,
        通过this来区分具体的对象

2.继承:
  2.1)作用:实现代码的复用,避免代码的重复
  2.2)通过extends来实现继承
  2.3)父类:所有子类所共有的属性和行为
      子类:子类所特有的属性和行为
  2.4)子继承父后,子具有: 父类的+子类的
  2.5)一个父类可以有多个子类,
      一个子类只能有一个父类----单一继承
  2.6)继承具有传递性
  2.7)java规定,构造子类之前必须先构造父类
      若子类构造中不调用父类的构造,则默认super()调用父类的无参构造
      若子类构造中调了父类的构造,则不再默认提供
      super()调用父类的构造必须位于子类构造的第一句

3.super:指代当前对象的父类对象
  super的用法:
    1)super.成员变量名------访问父类的成员变量
    2)super.方法名()--------调用父类的方法
    3)super()---------------调用父类的构造方法

4.向上造型:
  1)父类型的引用指向子类的对象
  2)能点出来什么,看引用的类型

//老虎是动物
Animal o3 = new Tiger(); //向上造型

class Animal{ //动物类
}
class Tiger extends Animal{ //老虎类
}

JAVA内存变量:
编译期,只检查语法是否正确
编译错误,指的是语法错误

运行期,JVM登场----分配内存

变量----占用的是JVM的内存

JAVA垃圾管理:
没有任何引用所指向的对象
垃圾回收器(GC),不定时到内存堆中清理垃圾
并非看到垃圾就立刻清理

垃圾回收过程是透明的(看不到的)
System.gc()让内存回收尽量快一些

内存泄露:

    没有用的内存还没有被及时的回收
         若对象不用了,及时将引用设置为null

堆-1

堆-2

方法区

程序一:

package oo.day03;

public class Cell {
int row;
int col; Cell(int row,int col){
this.row = row;
this.col = col;
} String getCellInfo(){
return row+","+col;
} }

Cell.java

package oo.day03;

public class Tetromino {
Cell[] cells; //格子数组,成员变量
// Cell[] cells=null; //如果没有下面cells = new Cell[4];声明操作,T.java里面会报索引错误 Tetromino() {
cells = new Cell[4]; //创建格子数组对象 } void drop(){
for(int i=0;i<cells.length;i++){
this.cells[i].row++;
}
} void moveLeft(){
for(int i=0;i<cells.length;i++){
this.cells[i].col--;
}
} void moveRight(){
for(int i=0;i<cells.length;i++){
this.cells[i].col++;
}
} void print(){
for(int i=0;i<cells.length;i++){
String str =this.cells[i].getCellInfo();
System.out.println(str);
}
}
}

Tetromino.java

package oo.day03;

public class T extends Tetromino {
T(){
this(0,0);
} T(int row,int col){
//super(); //调用父类的无参构造---默认参数
cells[0] = new Cell(row,col); //创建格子
cells[1] = new Cell(row,col+1);
cells[2] = new Cell(row,col+2);
cells[3] = new Cell(row+1,col+1);
}
}

T.java

package oo.day03;

public class J extends Tetromino{
J(){
this(0,0);
} J(int n){
this(n,n);
} J(int row,int col){
this.cells[0] = new Cell(row,col);
this.cells[1] = new Cell(row,col+1);
this.cells[2] = new Cell(row,col+2);
this.cells[3] = new Cell(row+1,col+2);
}
}

J.java

package oo.day03;

public class O extends Tetromino{
O(){
this(0,0);
} O(int n){
this(n,n);
} O(int row,int col){
this.cells[0] = new Cell(row,col);
this.cells[1] = new Cell(row,col+1);
this.cells[2] = new Cell(row+1,col);
this.cells[3] = new Cell(row+1,col+1);
}
}

O.java

package oo.day03;

public class TJTest {

    public static void main(String[] args) {

//    T t = new T(2,5);
// printWall(t);
Tetromino o1 = new T(2,5); //02.-1 向上造型
printWall(o1); //传值 J j = new J(1,6); //02.-2
printWall(j); //向上造型,同时传值 }
//打墙+打T型-----方法二:
// public static void printWall(T tt){
public static void printWall(Tetromino tt){ //01. 向上造型
// public static void printWall(T tt){ //01. 向上造型
// public static void printWall(J tt){ //01. 向上造型
for(int i=0;i<20;i++){ //控制行
for(int j=0;j<10;j++){ //控制行个数0
boolean flag = false; //1.假设打-
// i = 2 j = 5
for(int k=0;k<tt.cells.length;k++){ //这里循环4次;
if(i==tt.cells[k].row&& j==tt.cells[k].col){ //这里只取一次正确结果,如果有else,把“-”也会打上
flag = true; //因为有四个格子,所以循环4次,这里只取对的那次,
break;
}
}
if(flag){
System.out.print("* ");
}else{
System.out.print("- ");
}
}
System.out.println();
} /* //打墙+打T型----方法一
public static void printWall(T tt){
for(int i=0;i<20;i++){
for(int j=0;j<10;j++){
if(i==tt.cells[0].row&&j==tt.cells[0].col
||
i==tt.cells[1].row&&j==tt.cells[1].col
||
i==tt.cells[2].row&&j==tt.cells[2].col
||
i==tt.cells[3].row&&j==tt.cells[3].col){
System.out.print("* ");
}else{
System.out.print("- ");
} }
System.out.println();
}*/
} }

TJTest.java

增加打印“I am a T”

package oo.day04;
//T型
public class T extends Tetromino{
T(){
this(0,0);
}
T(int row,int col){
super(); //调用父类的无参构造---默认的
super.cells[0] = new Cell(row,col); //创建格子对象
super.cells[1] = new Cell(row,col+1);
super.cells[2] = new Cell(row,col+2);
super.cells[3] = new Cell(row+1,col+1);
} void print(){ //输出4个格子的行列号
System.out.println("I am a T:");
super.print(); //调用父类的print()方法
}
}

程序二:(类继承的演示)

upTypeDemo.java

package oo.day03;

public class UpTypeDemo {
public static void main(String[] args) {
Eoo o1 = new Eoo();
o1.e = 1;
o1.show();
//o1.f = 2; //编译错误,父类不能访问子类 Foo o2 = new Foo();
o2.f = 1;
o2.test();
o2.e = 2; //正确,子类可以访问父类
o2.show(); //正确,子类可以访问父类 Eoo o3 = new Foo(); //向上造型,语法:父类名字,子类的名字;
o3.e = 1; //这不是造型,这是访问成员,访问东西
o3.show();
//o3.f = 2; //编译错误,能点出来什么,看引用类型
//o3对应的是Eoo类,所以只能使用Eoo下面的方法;
}
} class Eoo{ //Eoo是父类
int e;
void show(){}
} class Foo extends Eoo{ //Foo是子类,继承Eoo父类
int f;
void test(){}
}

课后作业:

1 简述JVM垃圾回收机制

参考答案

垃圾回收机制是Java提供的自动释放内存空间的机制。

垃圾回收器(Garbage Collection,GC)是JVM自带的一个线程,用于回收没有被引用的对象。

2 Java程序是否会出现内存泄露

参考答案

会出现内存泄漏,一般来说内存泄漏有两种情况。

一是在堆中分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉;

另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。

第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。

下面给出了一个简单的内存泄露的例子。在这个例子中,我们循环申请Object对象,并将所申请的对象放入一个List中,如果我们仅仅释放引用本身,那么List仍然引用该对象,所以这个对象对GC来说是不可回收的。代码如下所示:

        List list=new ArrayList(10);
for (int i=1;i<100; i++)
{
Object o=new Object();
list.add(o);
o=null;
} 此时,所有的Object对象都没有被释放,因为变量list引用这些对象。

3 JVM如何管理内存,分成几个部分?分别有什么用途?说出下面代码的内存实现原理:

    Foo foo = new Foo();
foo.f();

参考答案

JVM内存分为“堆”、“栈”和“方法区”三个区域,分别用于存储不同的数据。

堆内存用于存储使用new关键字所创建的对象;栈内存用于存储程序运行时在方法中声明的所有的局部变量;方法区用于存放类的信息,Java程序运行时,首先会通过类装载器载入类文件的字节码信息,经过解析后将其装入方法区。类的各种信息(包括方法)都在方法区存储。

    Foo foo = new Foo();
foo.f();

以上代码的内存实现原理为:

1.Foo类首先被装载到JVM的方法区,其中包括类的信息,包括方法和构造等。

2.在栈内存中分配引用变量foo。

3.在堆内存中按照Foo类型信息分配实例变量内存空间;然后,将栈中引用foo指向foo对象堆内存的首地址。

4.使用引用foo调用方法,根据foo引用的类型Foo调用f方法。

Unit03 - 对象内存管理 、 继承的意义(上)的更多相关文章

  1. Objective-C 【单个对象内存管理(野指针&内存泄露)】

    ------------------------------------------- 单个对象内存管理 (1)野指针 ①定义了一个指针变量,但是并没有赋初值,它随机指向一个东西 ②某指针变量指向的内 ...

  2. oc48--多个对象内存管理练习

    // // main.m // 多个对象内存管理练习 // // ARC是Xcode帮我们生成内存释放的代码,MRC是需要我买自己写retain和release.想研究内存管理只能在MRC,管理对象就 ...

  3. Objective-C 【多个对象内存管理(野指针&内存泄漏)】

    ------------------------------------------- 多个对象内存管理(野指针&内存泄漏) (注:这一部分知识请结合"单个对象内存管理"去 ...

  4. 【cocos2d-x 3.x 学习笔记】对象内存管理

    内存管理 内存管理一直是一个不易处理的问题.开发人员必须考虑分配回收的方式和时机,针对堆和栈做不同的优化处理,等等.内存管理的核心是动态分配的对象必须保证在使用完成后有效地释放内存,即管理对象的生命周 ...

  5. iOS 非ARC基本内存管理系列 2-多对象内存管理(3) 利用@property来自动管理内存

    iOS 基本内存管理-多对象内存管理(2)中可以看到涉及到对象的引用都要手动管理内存:每个对象都需要写如下代码 // 1.对要传入的"新车"对象car和目前Person类对象所拥有 ...

  6. 引用计数的cocos2dx对象内存管理和直接new/delete box2d对象内存管理冲突的解决方法

    转载请注明: http://blog.csdn.net/herm_lib/article/details/9316601 项目中用到了cocos2dx和box2d,cocos2dx的内存是基于引用计数 ...

  7. iOS 非ARC基本内存管理系列 2-多对象内存管理(2)

    /* 多对象内存管理: 以人拥有车为例涉及到@property底层set方法管理内存的实现 注意:人在换车的时候要进行当前传入的车和人所拥有的车进行判断 */ /******************* ...

  8. iOS 非ARC基本内存管理系列 2-多对象内存管理(1)

    单个对象的内存管理非常简单无非就是alloc对应release,retain对应release.但是如果涉及到很多对象,而且对象与对象有联系的时候该怎么去管理对象的内存呢. 比如同样一本书有好3个人购 ...

  9. oc45--多对象内存管理 优化

    // // main.m // Set方法的内存管理 #import <Foundation/Foundation.h> #import "Person.h" #imp ...

随机推荐

  1. BZOJ2769 : YY的快速排序

    将数字离散化并去重,则对于一对逆序对$i<j$,$a_i>a_j$,贡献为$\frac{2}{a_i-a_j+1}$,因此只要对于每个差值统计出对应的逆序对个数即可. 将序列分块,块内平方 ...

  2. spark-sql访问hive的问题记录

    好久没有弄博客了... hive0.14 spark0.12 [hadoop@irs bin]$ ./spark-sql Spark assembly has been built with Hive ...

  3. MySQL数据类型和常用字段属性总结

    前言 好比C++中,定义int类型需要多少字节,定义double类型需要多少字节一样,MySQL对表每个列中的数据也会实行严格控制,这是数据驱动应用程序成功的关键.MySQL提供了一组可以赋给表中各个 ...

  4. sqlite 数据类型 全面

    http://blog.csdn.net/jin868/article/details/5961263 一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断.SQ ...

  5. topcoder SRM 618 DIV2 WritingWords

    只需要对word遍历一遍即可 int write(string word) { ; ; i < word.length(); ++ i){ cnt+=word[i]-; } return cnt ...

  6. Android --SeekBar的使用

    1. 效果图

  7. asp.net mvc4 HTTP Error 403.14

    asp.net mvc4项目部署到II&上时,出现HTTP Error 403.14 - Forbidden - The Web server is configured to not lis ...

  8. Install the Maven in your computer

    While, this blog will talk about installing the Maven in your computer. There are three steps as fol ...

  9. Spring MVC中处理静态资源的多种方法

    处理静态资源,我想这可能是框架搭建完成之后Web开发的”头等大事“了. 因为一个网站的显示肯定会依赖各种资源:脚本.图片等,那么问题来了,如何在页面中请求这些静态资源呢? 还记得Spring MVC中 ...

  10. C#:实现快捷键自定义设置(转)

    项目开发过程中,需要实现类似有道词典的软件设置中的自定义快捷键功能,如下图所示: 当我们相继按下Ctrl+Alt+M的时候,软件就会自动将快捷键显示在文本框中. 最终的效果如下图所示: private ...