Java内存区域

1、内存区域

  • jvm运行时数据区域

    • 程序计数器
    • Java虚拟机栈
    • 本地方法栈
    • 方法区
    • Java堆
  • 大图

2、概念解释

  • 程序计数器

      线程私有的一块很小的内存空间,它是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。每个线程都对应一个独立的程序计数器, 记录着线程执行指令,保障了线程间的切换后能恢复到正确的执行位置,从而保障了Java虚拟机多线程能有条不紊地轮流切换执行。

  • Java虚拟机栈

      线程私有, 它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

  • 本地方法栈

      为虚拟机使用到的native方法服务, 其作用类似于Java虚拟机栈, 只不过虚拟机栈为虚拟机执行Java方法(也就是字节码)服务。

  • 方法区

      各个线程共享的内存区域, 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区也是我们通常所说的永久区,它的大小可通过参数-XX:PermSize、-XX:MaxPermSize进行设置

  • Java堆

      Java堆是Java虚拟机所管理的内存中最大的一块, 被所有线程共享的一块内存区域, 在虚拟机启动时创建,是存储Java对象实例的地方。Java堆细分为:新生代和老年代,而新生代又可细分为Eden空间、from survivor空间、to survivor空间等。

      根据JVM规范,Java堆可以处于物理上不连续的内存空间中。只要逻辑上是连续的即可。可通过-Xmx设置最大Java堆的大小,-Xms设置初始化时Java堆大小。

3、为了更好理解堆、栈、方法区, 以下举个栗子

来,先看下一段代码

import java.text.SimpleDateFormat;
import java.util.Date; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* mvp
* @author yuanmeng
* @create 2017-06-18 下午8:44
**/
public class MVP { private static Logger LOG = LoggerFactory.getLogger(MVP.class); public void winMVP(String name) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String today = sdf.format(new Date()); LOG.info("威少 mvp");
}
}

这段程序的数据信息在内存中存放如下图所示:

垃圾收集器

**1)检测垃圾机制 **

  Java运行时所加载的数据, 如类信息、实例对象信息等会占用系统内存, 所幸的是Java有个强大的垃圾收集器, 在内存不够分配对象的时候会触发GC。

  检测垃圾的方法常见的有两种:1. 引用计数法;2. 可达性分析算法。

  • 引用计数法

      给对象附加一个引用计数器,只要有一个地方引用它,计数器值加1。当引用失效时就减1。任何时刻计数器都为0的对象就是不可能再被使用的,将其判定为可回收的对象。这种检测机制的优点是很简单, 但它有个很致命的缺点,它无法解决对象间循环引用问题。如hashMap在高并发的时候会出现循环链表问题。

  • 可达性分析算法

      主流的JVM基本都使用可达性分析算法来判断对象是否存活,通过一系列“GC Roots”的对象作为起始点向下搜索,搜索所走过的路径为引用链,当一个对象没有任何引用链与GC Roots相连,代表该对象不再被使用,将其判定为可回收的对象。

看下图,Object5 、Object6、Object7是从跟节点出发无法可达到的对象, 可判定为回收对象。

2)回收垃圾机制

  • 标记-清除算法

      先标记待回收的对象,然后再对标记的对象进行清除。图解



    这种算法缺点 :

    • 标记和清除两个过程, 效率不高
    • 标记清除后会产生大量不连续内存碎片, 多次进行标记和清除回收后可能会导致以后程序在运行过程中需要分配大对象时,无法找到足够的连续内存而不得不提前出发GC,而GC需要耗时间。
  • 复制算法

      复制算法是将内存分成两块,一块存储程序运行分配的对象,一块是空闲区域。当存储对象的内存区域用完了,会将此区域存活的对象复制到另一块空闲区域,然后再把已使用的内存空间一次清理掉。

复制算法实现简单、高效。但代价有点大了,可用内存缩小为原来的一半,以“空间换取时间”。

  • 标记-整理算法

  标记-整理算法是对原有标记-清除算法进行的改造,不是直接对可回收对象进行清理,而是让所有存活对象都向另一端移动,然后直接清理掉端边界以外的内存。

  • 分生代算法

   前面也介绍过了,Java堆内存可以细分为新生代、老年代。新生代生存的生命周期比较短,每次经过GC后仍存活的对象年龄会加1, 多次GC后仍存活的对象会直接晋升为老年代。而老年代的生命周期比较长。换句话说,每次GC后新生代生存下来的对象很少,老年代存活对象多。前面分析过,生存对象少的新生代更适合用复制算法,生存对象多的老年代适合用标记-清除或者标记-整理算法

参考文献

《深入理解Java虚拟机》

写在最后

新博客请移步

Java内存分配及垃圾回收机制(未完待待续)的更多相关文章

  1. Java内存分配及垃圾回收机制

    Java内存区域 1.内存区域 jvm运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 方法区 Java堆 大图 2.概念解释 程序计数器   线程私有的一块很小的内存空间,它是当前线程所执行 ...

  2. Java 内存分配及垃圾回收机制初探

    一.运行时内存分配 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则 ...

  3. JVM内存分配与垃圾回收机制管理

    项目上线,性能优化有个重要组成就是jvm内存分配和垃圾回收机制的管理配置. 网上随便能搜到相关的具体步骤,以及内存中各种参数对应的意义,不再赘述. 干货就是直接抛出遇到的问题,以及如何解决的,再说说待 ...

  4. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

  5. java内存分配与垃圾回收

    JVM的内存分配主要基于两种,堆和栈. 我们来看一下java程序运行时候的内存分配策略: 1):静态存储区(方法区): 2):栈区: 3):堆区: 1):主要存放静态数据,全局static数据和常量. ...

  6. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  7. 巩固java(二)----JVM堆内存结构及垃圾回收机制

    前言:        我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构   ...

  8. Java中内存泄露及垃圾回收机制

    转自:http://blog.sina.com.cn/s/blog_538b279a0100098d.html 写的相当不错滴...................... 摘  要 Java语言中,内 ...

  9. CLR、内存分配和垃圾回收

    一.CLR CLR:即公共语言运行时(Common Language Runtime),是中间语言(IL)的运行时环境,负责将编译生成的MSIL编译成计算机可以识别的机器码,负责资源管理(内存分配和垃 ...

随机推荐

  1. Ajaxfileupload 总结(包括插件处理json格式bug的解决方案)

    Ajaxfileupload 是一款轻量级js的上传插件,简单容易上手,今天简单学习了下. 1,引用jquery和Ajaxfileupload .js <script src="~/S ...

  2. IOS的控制器

    控制器简单来说,就是用来做界面跳转的,类似于 Android 的Intent 1.创建一个控制器 控制器的常见的创建方式 )通过storyboard创建 //直接创建 NJViewController ...

  3. java.util.NoSuchElementException: None.get的解决方法

    在Java中用null表示无值返回.在Java 里,null 是一个关键字,不是一个对象,所以对它调用任何方法都是非法的 笔者就常在类型转换时见到空指针错误,便是由null的特殊性导致的 而在scal ...

  4. CSS3特效----制作3D旋转照片展示区

    任务一.制作多背景 提示:上层有一个径向渐变,渐变图像farthest-side ellipse at center,  rgba(246,241,232,.85) 39%,rgba(212,204, ...

  5. 微信小程序开发流程

    2017年1月9日,张小龙在2017微信公开课Pro上发布的小程序正式上线,一夜之间,小程序可谓家喻户晓,但通过接下来的几个月的观察,微信小程序并没有想象中的那么火爆.进入4月以来,微信小程序团队进行 ...

  6. Java Stack源码分析

    Stack简介 Stack是栈.它的特性是:先进后出(FILO, First In Last Out).java工具包中的Stack是继承于Vector(矢量队列)的,由于Vector是通过数组实现的 ...

  7. wdc网站部署问题

    最近公司新买了一个服务器,将项目迁移到新服务器上,按照wdcp安装方法,部署了lnamp环境,具体方法如下: 安装方法1 只安装wdcp面板看看wget http://down.wdlinux.cn/ ...

  8. H5水果机,一个网络版的lao hu ji

    该游戏为h5小游戏,纯属娱乐,技术探讨,相关技术在文章结尾,欢迎探讨交流 花了几天时间开发了这款水果lao hu ji,更新了几个版本,还有不足的地方,由于时间有限暂时没有继续更新新版本 未完成的功能 ...

  9. Vuejs实例-02Vue.js项目集成ElementUI

    Vuejs实例-02Vue.js项目集成ElementUI 0:前言 vue.js的UI组件库,在git上有多个项目,我见的使用者比较多的是iView和Element.两个组件库,组件都很丰富. 官网 ...

  10. elasticsearch 不能通过9200端口访问

    修改配置文件 config/elasticsearch.yml network.host: 0.0.0.0