zoukankan      html  css  js  c++  java
  • java内存分配与垃圾回收

    JVM的内存分配主要基于两种,堆和栈。

    我们来看一下java程序运行时候的内存分配策略

    1):静态存储区(方法区);

    2):栈区;

    3):堆区;

    1):主要存放静态数据,全局static数据和常量。

    2):在java中,栈的分配是和线程绑定在一起的,当我们创建一个线程的时候,很显然,JVM就会为这个线程创建一个java栈,一个线程的方法的调用和返回对应于这个java栈的压栈和出栈。当线程激活一个java方法时,JVM就会线程的java堆栈里新压入一个帧,这个帧自然成了当前帧。在此方法执行期间,这个帧用来保存参数,局部变量,中间计算过程和其他数据。

    栈中主要存放一些基本类型的变量数据(int,short,long,byte,float,double,boolean,char)和对象的句柄(引用)。方法体内的局部变量都在栈上创建的。

    优点:存取速度比堆快,仅次于寄存器,栈数据可以共享。

    缺点:存在栈中的数据大小与生存期必须是确定的,因此缺乏灵活性。

    3):每个java应用都唯一对应一个JVM实例,每个实例唯一对应一个堆。堆是一个运行时数据区。

    堆中存放的是应用程序在运行中所创建的所有类实例或数组,并由应用程序的所有线程贡献。这些对象通过new,newarray,anewarray和multianewarray等指令建立。

    优点:堆由垃圾回收来负责,可以动态的分配内存大小,生存期也不必实现告诉编译器,因为它是在运行时动态分配内存的,java的垃圾收集器会自动收走这些不再使用的数据。

    缺点:由于要在运行时动态分配内存,存取速度较慢。

    在java中分配堆内存是自动初始化的,所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配的。因此建立一个对象的时候两个地方都要分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。

    接下来我们看一下java的垃圾回收机制。

    当堆内存不再被任何引用变量引用的时候,这块内存就变成垃圾,等待垃圾回收机制进行回收。

    java的垃圾回收机制的特点:

    1、只负责回收堆内存的中的对象,不回收任何物理资源(如数据库的连接,网络IO等资源)。

    2、程序无法精确地控制垃圾回收的运行,其会在合适的时候运行。当对象永久性地失去引用后,系统就会在合适的时候回收它所占用的内存。

    3、在垃圾回收机制回收任何对象之前,总会先调用它的finalize()方法,该方法可能使该对象重新复活(让一个引用变量重新引用该对象),从而使垃圾回收机制取消回收。

    堆内存中的对象可以分为三种状态:

    1、可达状态:被一个以上的引用变量引用。

    2、可恢复状态:没有引用变量引用它,系统的垃圾回收机制准备回收该对象占有的内存,在这之前系统会调用可恢复状态对象的finalize()方法进行资源清理,若是调用该方法时重新让一个引用变量引用该对                               象,那么这个对象会再次变为可达状态,否则进入不可达状态。

    3、不可达状态:当系统处于这种状态的时候,系统才会真正回收该对象所占有的资源。

    程序是无法精确地控制垃圾回收何时进行,但是可以强制系统进行垃圾回收,这只是对系统的一种建议,系统是否进行垃圾回收是不确定的。垃圾回收也不会对程序的建议完全置之不理:垃圾回收机制会在收到通知后尽快进行垃圾回收。

    强制垃圾回收有以下两种方式:

    1、System.gc().

    2、Runtime.getRuntime().gc().

  • 相关阅读:
    python写的百度贴吧相册下载
    C#的图片拼接
    删除目录下的所有".svn"文件
    centOS 6.5 yum升级 gcc4.8 然后又退回来4.4
    代理的分类简述特点
    GCC 特性整理
    纯C 实现 strpos substr strspilt str_trim
    编译putty 源码去掉 Are you sure you want to close this session? 提示
    OpenWrt tcpdump 抓包
    安卓 打飞机 app 开发 第一篇
  • 原文地址:https://www.cnblogs.com/tangZH/p/7682274.html
Copyright © 2011-2022 走看看