zoukankan      html  css  js  c++  java
  • JVM的内存管理、对象的生命周期、内存泄漏

    1 JVM内存

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

      1.1 堆

        JVM在其内存空间开辟一个称为”堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象。

      1.2 栈

        JVM在其内存空间开辟一个称为”栈”的存储空间,这部分空间用于存储程序运行时在方法中声明的所有局部变量。

      1.3 方法区

        方法区用于存放类的信息,Java程序运行时,首先会通过类装载器载入类文件的字节码信息,经过解析后将其装入方法区,类的各种信息(包括方法)都在方法区存储。

    2 对象的生命周期

      2.1 使用new运算符创建对象

        2.1.1 Java虚拟机先检查类是否加载, 如果没有加载就加载类信息到方法区

        2.1.2 根据类信息中的属性定义在堆内存中开辟存储空间, 并且每个属性有默认值

        2.1.3 调用构造器, 执行构造器中属性初始化过程, 构造器结束时候, 释放构造器中全部的局部变量

        2.1.4 new运算返回对象的引用(即:对象在堆中的地址)

      2.2 利用引用操作使用对象 - 使用引用操作对象: 访问对象的属性和方法. - 可以反复更改对象的属性状态.

      2.3 对象在不被引用时候被垃圾回收器回收 - 当一个对象不再被引用时候, 对象就称为内存垃圾. 内存垃圾在适当时候被垃圾回收器回收.

      2.4 注意

        2.4.1 对象生存期中构造器只能执行一次. 在对象生存期间, 可以反复调用其方法, 反复访问其属性. 

        2.4.2 对象的属性随着对象在堆中分配.

      2.5 图片示意图

        

      2.6 代码实现

     1 public class Demo {
     2     public static void main(String[] args) {
     3         //对象的生命周期
     4         Circle c1 = new Circle(3, 4, 5);
     5         System.out.println(c1);
     6         Circle c2 = new Circle(3, 4, 6);
     7         System.out.println(c2);
     8         //将引用赋值为null, 对象不再被引用
     9         //对象变成内存垃圾, 将被垃圾回收器回收.
    10         c1=null;
    11         c2=null;
    12     }
    13 }
    14 class Circle{
    15     int x,y,r;
    16 
    17     public Circle(int x, int y, int r) {
    18         this.x = x;
    19         this.y = y;
    20         this.r = r;
    21     }
    22 
    23     public String toString() {
    24         return x+","+y+","+r;
    25     }
    26 }
    View Code

    3 内存泄漏

      尽管Java的垃圾回收器可以回收堆内存, 但是当Java程序员操作对象不当时候, Java也会发生内存泄漏.

      3.1 什么情况下会发生内存泄漏

        应用程序大量创建对象, 并且保持这些对象的引用, 进而造成垃圾回收器不能有效释放对象占用的堆内存空间, 最终内存耗尽出现内存泄漏.

      3.2 避免内存泄漏的方法

        对象使用以后,及时将引用对象的引用变量赋值为null, 使对象变成垃圾对象, 及时被回收并且释放堆内存, 就可以避免内存泄漏.

      3.3 代码实现

     1 package cn.fury.day11;
     2 
     3 public class MemoryLeakDemo01 {
     4     public static void main(String[] args) {
     5         Foo[] ary = new Foo[40000000];
     6         for(int i=0; i<ary.length; i++){
     7             Foo f = new Foo();
     8 //            f = null;
     9             ary[i] = f; // 创建了许多对象,并且将对象的引用(即:地址)放到了一个数组里面
    10         }
    11     }
    12 }
    13 class Foo{
    14     int a;
    15     int b;
    16     int c;
    17 }
    18 /*
    19 尽管Java的垃圾回收器可以回收堆内存, 但是当Java程序员操作对象不当时候, Java也会发生内存泄漏.
    20     》何时发生内存泄漏: 应用程序大量创建对象, 并且保持这些对象的引用, 
    21 进而造成垃圾回收器不能有效释放对象占用的堆内存空间, 最终内存耗尽出现内存泄漏.
    22     》避免内存泄漏的办法: 对象使用以后,及时将引用对象的引用变量赋值为null, 
    23 使对象变成垃圾对象, 及时被回收并且释放堆内存, 就可以避免内存泄漏.
    24 */
    View Code
  • 相关阅读:
    事务创建函数
    实现Xshell断开连接情况下Linux命令继续执行
    MySQL UNION 操作符
    CentOS安装部署Mysql 5.7
    连接数据库
    @Results用法总结
    在Java中如何高效的判断数组中是否包含某个元素
    Java中的map集合顺序如何与添加顺序一样
    instanceof的用法
    枚举
  • 原文地址:https://www.cnblogs.com/NeverCtrl-C/p/6486156.html
Copyright © 2011-2022 走看看