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. trait技术详解,这次包你学得会

    trait的使用技巧trait是php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公共trait类,就像是装配汽车的配件,如果你的类中要用到这些配件,就直接用use导入 ...

  2. WPF报表自定义通用可筛选列头-WPF特工队内部资料

    由于项目需要制作一个可通用的报表多行标题,且可实现各种类型的内容显示,包括文本.输入框.下拉框.多选框等(自定的显示内容可自行扩展),并支持参数绑定转换,效果如下: 源码结构 ColumnItem类: ...

  3. UI—视图的生命周期

  4. [刷题]算法竞赛入门经典(第2版) 4-10/UVa815 - Flooded!

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa815 - Flooded! #include<iostream ...

  5. FileInputStream和FileOutputStream详解

    一.引子 文件,作为常见的数据源.关于操作文件的字节流就是 FileInputStream & FileOutputStream.它们是Basic IO字节流中重要的实现类.二.FileInp ...

  6. 单词计数,杭电0j-2072

    原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=2072 [Problem Description] lily的好朋友xiaoou333最近很空,他想了一 ...

  7. progressBar的使用

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. Java基础知识二次学习--第七章 容器

    第七章 容器   时间:2017年4月27日15:08:30 章节:07章01节~07章04节 视频长度:20:21 +12:38 +3:55 +2:57 内容:容器API 心得: Java API ...

  9. 百度前端技术学院—-小薇学院(HTML+CSS课程任务)

    任务一:零基础HTML编码 课程概述 作业提交截止时间:04-24 重要说明 百度前端技术学院的课程任务是由百度前端工程师专为对前端不同掌握程度的同学设计.我们尽力保证课程内容的质量以及学习难度的合理 ...

  10. Fast data loading from files to R

    Recently we were building a Shiny App in which we had to load data from a very large dataframe. It w ...