文档章节

JVM学习04:运行时数据区域-JAVA堆

翰霖学院
 翰霖学院
发布于 2017/07/24 08:59
字数 1250
阅读 1
收藏 0

这里写图片描述
这里写图片描述
The heap is the runtime data area from which memory for all class instances and arrays is allocated。

  1. Java heap是Java虚拟机中内存最大一块区域,也是最该小心的区域,因为内存溢出一般都在这块区域发生。
  2. Java heap是被线程共享的内存区域,在虚拟机启动的时候创建。
  3. 该区域存储的是实例化对象和数组的真实地址,由于线程共享所以在共享是该区域的对象时需要注意同步
  4. 注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。对象使用方法的时候方法才被压入栈,方法不使用则不占用内存。方法的调用是由java栈中的栈帧来完成入栈出栈的使用,Java对象中包含的基本数据由他所属的类及其所有超类声明的实例变量组成。只要有一个对象引用,虚拟机就必须能够快速的定位对象实例的数据。另外,它也必须能通过该对象引用访问相应的类数据(存储于方法区的类型信息)。因此在对象中通常会有一个指向方法区的指针。
  5. Java虚拟机有一条在堆中分配对象的指令,却没有回收该对象的指令。由于对象的频繁创建,会导致java heap区域内存逐渐缩小,对于不在被使用的对象会大大浪费内存空间,因此Java虚拟机中引入了垃圾回收。Java heap是垃圾回收器的主要战场。
  6. 根据Java虚拟机规范,java heap可以处于物理地址不连续的内存空间中,只要在逻辑地址中保持连续即可,就像磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的。(通过-Xmx和-Xms控制
  7. 如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常
  8. 由于现在收集器基本采用分代收集算法,所以JAVA堆还可以细分为:新生代和老年代,再细分还有Eden空间、From Survivor空间、To Survivor空间。 其主要思想与Java GC有关系,即大部分对象的存活时间都比较短,如果某一个对象存活时间比较长,就把他移到另外一个区域。这样做GC的成本比较低。(后续的文章中会重点讲述该区域的分配与回收

    其他说明
    其大小通过-Xms(最小值)和-Xmx(最大值)参数设置,-Xms为JVM启动时申请的最小内存,默认为操作系统物理内存的1/64但小于1G,-Xmx为JVM可申请的最大内存,默认为物理内存的1/4但小于1G,默认当空余堆内存小于40%时,JVM会增大Heap到-Xmx指定的大小,可通过-XX:MinHeapFreeRation=来指定这个比列;当空余堆内存大于70%时,JVM会减小heap的大小到-Xms指定的大小,可通过XX:MaxHeapFreeRation=来指定这个比列,对于运行系统,为避免在运行时频繁调整Heap的大小,通常-Xms与-Xmx的值设成一样。
    由于现在收集器都是采用分代收集算法,堆被划分为新生代和老年代。新生代主要存储新创建的对象和尚未进入老年代的对象。老年代存储经过多次新生代GC(Minor GC)任然存活的对象。
    新生代:
    程序新创建的对象都是从新生代分配内存,新生代由Eden Space和两块相同大小的Survivor Space(通常又称S0和S1或From和To)构成,可通过-Xmn参数来指定新生代的大小,也可以通过-XX:SurvivorRation来调整Eden Space及Survivor Space的大小。
    老年代:
    用于存放经过多次新生代GC任然存活的对象,例如缓存对象,新建的对象也有可能直接进入老年代,主要有两种情况:①.大对象,可通过启动参数设置-XX:PretenureSizeThreshold=1024(单位为字节,默认为0)来代表超过多大时就不在新生代分配,而是直接在老年代分配。②.大的数组对象,切数组中无引用外部对象。
    老年代所占的内存大小为-Xmx对应的值减去-Xmn对应的值。
    这里写图片描述
    这里写图片描述

© 著作权归作者所有

翰霖学院
粉丝 0
博文 67
码字总数 45112
作品 0
济南
高级程序员
私信 提问
JVM内存结构 VS Java内存模型 VS Java对象模型

Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模型和...

Java架构
2018/07/11
0
0
JVM学习总结(一)运行时数据区

《深入Java虚拟机》这本书买了有一段时间了,当时看的时候就只是看,并没有边看边总结啥的,最后发现到脑子里面的根本所剩无几了。现在开始要好好归纳总结地再学习一遍。 运行时数据区域 JV...

hensemlee
2018/04/22
154
0
JVM 运行时数据区简介及堆与栈的区别

理解JVM运行时的数据区是Java编程中的进阶部分。我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机制,...

大数据之路
2015/08/02
4K
1
JVM虚拟机内存-学习笔记-超精简版-1

原文更详细:https://www.cnblogs.com/dingyingsi/p/3760447.html 程序计数器: 1、一块较小的内存空间,作用是当前线程所执行的字节码的行号指示器。(Java 虚拟机的多线程是通过线程轮流切...

Kidult
2018/08/07
20
0
虚拟机学习之一:java内存区域与内存溢出异常

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

贾峰uk
2018/10/21
45
1

没有更多内容

加载失败,请刷新页面

加载更多

Netty整合Protobuffer

现在我们都知道,rpc的三要素:IO模型,线程模型,然后就是数据交互模型,即我们说的序列化和反序列化,现在我们来看一下压缩比率最大的二进制序列化方式——Protobuffer,而且该方式是可以跨...

算法之名
9分钟前
7
0
如何用C++实现栈

栈的定义 栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压...

BWH_Steven
28分钟前
3
0
编程作业20190210900169

1编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。 #include <stdio.h>#include <stdlib.h> int main(){ char firstName[20]; char lastName[20]; print......

1李嘉焘1
40分钟前
6
0
补码的优点及原理分析

只讨论整数 1.计算机内部为什么没有减法器? 减法运算本身其实就是加法,如x - y即x +(-y),所以只需要将负数成功表示出来并可以参加加法运算,那加法器就可同时实现“+”和“-”的运算。这...

清自以敬
55分钟前
73
0
Docker 可视化管理 portainer

官网安装指南: https://portainer.readthedocs.io/en/latest/deployment.html docker-compose.yml 位置,下载地址:https://downloads.portainer.io/docker-compose.yml...

Moks角木
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部