Java虚拟机内存区域堆(heap)的管理

在上一节中Java 出现内存溢出的定位以及解决方案 中对于Java虚拟机栈以及方法区的内存出现的异常以及处理方式进行了解析,由于Java虚拟机对于堆的管理十分复杂,并且Java虚拟机中最基本的内存区域,所以单独提出一节进行分析。

先来解释一下对象存活??

什么样的对象是已经死了的对象,须要垃圾回收器进行回收。这个概念至关重要。由于它影响到垃圾回收器对于哪一个对象进行回收。能够从GCRoot訪问到的对象是存活的对象,那么以外的对象就是已死的对象。

GCRoot:包含四种 1)Java虚拟机栈中存放的reference指针指向的对象   2)本地方法栈中reference指向的对象  3)方法区中的常量引用对象 4)方法区中静态类属性引用的对象

GC 垃圾回收器

垃圾回收器採用的是标记-清除-整理算法回收内存。

Minor GC和Full GC。Minor GC是对年轻代回收的过程。 Full GC 是对整个堆以及方法区进行回收的过程。

分代收集。在Java虚拟机中对于堆的内存区域进行再划分为,Young Generation(年轻代)和Old Generation(老代)

年轻代用于存储年龄没有达到-XX:PretenureSizeThreshold的对象,老代用于存储年龄超过了-XX:PretenureSizeThreshold的对象。

然后对于年轻代再进行细分,Eden Space, From Space, ToSpace三个内存区域,这三个内存区域的大小由-XX:SurivorRadio来定义。在进行Minor GC的时候,会将Eden Space和From Space中存活的对象Copy到ToSpace中,并将超过春节龄的对象Copy到老代。当老代空间不足时,启动Full GC。

(上面概念仅仅是进行了简单的描写叙述,在JVM实际执行过程中要复杂的多,只是大概原理是这种)。

了解了上面基本概念之后,看以下的垃圾回收器就比較简单了。垃圾回收器总共分为七种:Serial收集器与Serial Old
收集器。Parallel Scavenge
收集器与Parallel Old,ParNew收集器,CMS收集器,G1(Garbage First)收集器。

1.Serial收集器与Serial Old
收集器。分别用于收集年轻代和老年代内存区域,Serial是单线程的垃圾收集器。在执行过程中须要暂停全部的Java线程。

2.ParNew收集器实际上就是Serial收集器的多线程版本号(针对于年轻代)。

3.Parallel Scavenge
收集器与Parallel Old: 是并行的多线程垃圾处理器,能够规定最大垃圾收集停顿时间-XX:MaxGCPauseMillis以及设置吞吐量大小-XX:GCTimeRadio.

4.CMS
收集器(Concurrent Mark Sweep): 是针对于老年代的多线程并发运行的垃圾回收器。以获取最短回收停顿时间为目标的收集器(主要用于B/S架构的server上)

5.
G1(Garbage First)收集器: 是最新的垃圾回收器,适合于(JDK1.6_update14)以上的JVM;G1将整个Java堆(包含新生代和老年代)划分为多个固定大小的独立区域,而且跟踪这些区域里面的垃圾堆积程度,在后台维护一个垃圾优先列表,每次依据同意收集的时间,优先回收垃圾最多的区域。

总之,要想获得最大吞吐量的服务类型就採用Parallel Scavenge 收集器与Parallel Old收集器组合。

要实现实时系统最好採用CMS 收集器(Concurrent Mark Sweep)。

只是client因为比較小,还是使用Serial比較好。

时间: 2024-11-16 13:35:26

Java虚拟机内存区域堆(heap)的管理的相关文章

Java虚拟机内存区域详解

众所周知,Java程序运行于Java虚拟机(JVM)上,那么,JVM运行的时候内存是如何分配的呢?程序中各部分变量都存储在内存的哪个部分,又如何访问,下面,就让我来给大家讲解Java虚拟机内存区域. 为什么需要了解Java虚拟机内存区域 相对于C++程序员,因为虚拟机的自动内存管理机制的存在,Java程序员很多时候并不需要去担心内存的泄露和内存溢出的问题.但是正是因为把内存的控制权交给了JVM,一旦出现内存泄露和溢出的问题,如果不了解虚拟机怎么使用内存,就很难排查错误. 内存泄露:一些对象在使用

java虚拟机内存区域理解

java虚拟机有的区域随着虚拟机进程的启动而存在, 有的区域依赖用户线程的启动和结束而建立和销毁. 程序计数器:为了线程切换后能恢复到正确的执行位置,每个线程都有一个独立的程序计数器.(针对java方法,即栈) 虚拟机栈:为了虚拟机执行java方法,线程创建时就会创建一个栈帧,存储局部变量表.操作数栈.动态链接等. StackOverFlowError:线程请求的栈深度大于虚拟机所允许的深度: OutOfMemoryError:动态扩展是无法申请到足够的内存. 本地方法栈:为了虚拟机使用到Nat

《深入理解Java虚拟机》笔记 第二章 Java虚拟机内存区域

? ? 这句话感觉道出了GC的本质 ? ? ? ? ? ? 1.程序计数器(Program Counter Register) ? ? 程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器.字节码解释器工作时就是通过改为这个计数器的值来选取下一条需要执行的字节码指令,分支.循环.跳转.异常处理.线程恢复等基础功能都需要依赖这个计数器来完成. ? ? 由于Java虚拟机的多线程是通过线程轮流切换CPU时间片的方式来实现的,所以在任何一个时刻,一个处理器(对于多核处理

Java 虚拟机内存区域划分详解(1)

一.概述 对于 C 和 C++程序开发的开发人员来说,在内存管理领域,程序员对内存拥有绝对的使用权,但是也要主要到正确的使用和清理内存,这就要求程序员有较高的水平. 而对于 Java 程序员来说,在虚拟机的自动内存管理机制的帮助下,不再需要为每一个 new 操作去写配对的 delete/free 代码,而且不容易出现内存泄漏和内存溢出问题,看起来由虚拟机管理内存一切都很美好.不过,也正是因为 Java 程序员把内存控制的权力交给了 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚

java虚拟机内存区域的划分以及作用详解

序言 为什么有时候学着学着会突然之间觉得一切度是那么无趣,男的每个月也有那么几天难道?哈哈,不然是什么,我还是要坚持,可以做少一点,但是不能什么度不做.总会过去的,加油 --WH 一.运行时数据区 什么叫运行时数据区呢,看下图就知道了,今天的重点就围绕这张图讲. 1.程序计数器(寄存器) 当前线程所执行的字节码行号指示器 字节码解释器工作依赖计数器控制完成 通过执行线程行号记录,让线程轮流切换各条线程之间计数器互不影响 线程私有,生命周期与线程相同,随JVM启动而生,JVM关闭而死 线程执行Ja

Java虚拟机内存区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间.根据Java虚拟机规范,包括以下几个运行时数据区. 一.程序计数器 内存空间:较小. 作      用:当前线程所执行的字节码的行号指示器. 特性分析:Java虚拟机的多线程的执行是由线程轮流切换并分配处理器执行时间来完成的.在确定的某个时刻,一个处理器只会执行一条线程中的指令.因此,为了线程切换后能恢复到正确的的执行位置,每条线程都需要一个独立的程序计数器,各个线

java虚拟机内存划分

java虚拟机内存区域 参照官方文档 1.8版本 Oracle虚拟机内存划分文档 : https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5 The Java Virtual Machine defines various run-time data areas that are used during execution of a program. Some of these data areas are

从一道面试题深入了解java虚拟机内存结构

记得刚大学毕业时,为了应付面试,疯狂的在网上刷JAVA的面试题,很多都靠死记硬背.其中有道面试题,给我的印象非常之深刻,有个大厂的面试官,顺着这道题目,一直往下问,问到java虚拟机的知识,最后把我给问住了. 我当时的表情是这样的: 后来我有机会面试别人了,也按照他的思路出面试题,很多已经工作了2年的程序员,结果也和我当年一样,都败在java虚拟机知识上. 我们先看面试题: String str1 = "hello Alunbar"; String str2 = new String(

关于java虚拟机内存管理的一些讲解

java数据类型: 1)原始类型:Primitive Types(原始值) 数值类型(Numeric Types) 整型类型(Integral Types),浮点类型(Floating-Point Types) 布尔类型(Boolean Types) returnAddress类型:表示一条字节码指令的操作码(Opcode).在所有的虚拟机支持的原始类型之中,只有 returnAddress 类型是不能直接 Java 语言的数据类型对应起来的. 2)引用类型:Reference Types(引用