JVM的内存结构、内存溢出、内存泄漏、内存模型你知道吗?

Stella981
• 阅读 369

JVM的内存结构、内存溢出、内存泄漏、内存模型你知道吗?

JVM的内存结构、内存溢出、内存泄漏、内存模型你知道吗?

1、JVM内存结构

Java8后,内存分成如下几部分:程序计数器PC Register,Metaspace,Stack,Heap,和本地方法栈。

JVM的内存结构、内存溢出、内存泄漏、内存模型你知道吗?

Metaspace用于存放类的元信息以及方法信息;而常量池和静态变量存在Heap中。Heap里面存储运行时产生的对象。Stack里面存放线程相关的数据,如局部变量,参数,对象引用等。PC Register存放的是当前线程执行的指令地址。本地方法栈是调用本地方法时用到的。

上图左边的Metaspace和Heap在JVM中是唯一的,全部线程都会共享这两片区域。右边的Stack/本地方法stack/程序计数器则是线程相关的。

从物理内存来讲,Metaspace不再使用虚拟机的内存,而是直接使用本地内存,由操作系统管理,仅受本地内存大小限制。
调整Metaspace内存大小的参数 

-XX:MetaspaceSize -XX:MaxMetaspaceSize

堆区Heap:
(1)存储的全部是对象。
(2)存放的这些对象是程序运行时动态创建的。
(3)jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身。
(4)常量池和静态变量存在Heap中。
栈区Stack:
(1)每个线程包含一个栈区,栈中只保存基础数据类型的对象和动态创建的对象的引用(对象本身都存放在堆区中)。
(2)每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
(3)由编译器自动分配释放,存放函数的参数值,局部变量的值等.

2、JVM内存溢出

内存溢出是指程序申请内存时,没有足够的内存供申请者使用。原因可能是:
A,数据加载过多,如一次从外部获取过多数据  
B,集合类中有对对象的引用,用完后没有清空或者集合对象未置空导致无法回收
C,循环中产生过多重复对象
D,启动参数内存值设定的过小。

解决的方法:修改JVM启动参数,加内存(-Xms,-Xmx);错误日志,是否还有其他错误;代码走查

3、JVM内存泄露

内存泄漏是指程序申请并使用内存后一直不释放,内存一直占用着。一次泄露不会有明显影响,累积泄露会导致OOM(内存溢出)。典型的现象就是系统频繁FullGC,直到最后OOM(Out of Memory)。
排查方法:使用各种profiling工具进行排查,如VisualVM,JProfiler等。可以先用jmap查看那些对象占用了大量内存,然后用btrace定位程序代码。
内存泄漏是由于代码不善引起的,要注意程序一些容易犯错的地方:
对不再使用的对象要置为null,尽早释放无用对象的引用;
程序避免用String拼接,用StringBuffer,因为每个String会占用内存一块区域;
尽量少用静态变量(全局不会回收);
及时关闭资源,在finally里面释放,或者用try-with-resources自动关闭;
定义新类时,没有重写equals()和hashCode()方法,导致隐患;
不当使用ThreadLocal造成的内存泄漏,应该在不再使用ThreadLocals时remove();
另外,服务器session时间设置过长也可能会引起内存泄漏。

2、Java内存模型

       java内存模型(Java Memory Model,JMM)java虚拟机规范定义的,用来屏蔽掉java程序在各种不同的硬件和操作系统对内存的访问的差异,从而实现java程序在各种不同的平台上都能达到内存访问的一致性。
Java内存模型的主要目标是定义程序中变量的访问规则。可以简单的认为主内存是java虚拟机内存区域中的堆,局部变量和方法参数是在虚拟机栈中定义的。但是在堆中的变量如果在多线程中都使用,就涉及到了堆和不同虚拟机栈中变量的值的一致性问题了。
虚拟机规定,线程对主内存变量的修改必须在线程的工作内存中进行,不能直接读写主内存中的变量。不同的线程之间也不能相互访问对方的工作内存。如果线程之间需要传递变量的值,必须通过主内存来作为中介进行传递。

JVM的内存结构、内存溢出、内存泄漏、内存模型你知道吗?

java内存中线程的工作内存和主内存的交互是由java虚拟机定义了8种原子操作来完成的:lock unlock read load use assign store write。对于这8种操作,虚拟机也规定了一系列规则,在执行操作的时候必须遵循

小贴士

返回上一级微信公众号对话框

回复“ m“ 关键词即可获取相关开发工具推荐。

回复“书籍”关键字即可获取相关书籍推荐。

回复“资源”关键字即可获取开发资源大全。

回复“666”关键字即可获取《面试宝典》。

回复“1024”关键字试试?

下方菜单栏点击餐饮部-Java餐-阅读原创书籍。

后续会持续更新更多书籍及优质资源推荐,敬请期待哦!

       

JVM的内存结构、内存溢出、内存泄漏、内存模型你知道吗?

Java面试机经(初级篇-19期)

● Java设计模式~单例模式

●  这套面试题你能答出来多少?

●  Linux简介及最常用命令(建议先收藏)

● 工程化专题之Maven(上)

● 工程化专题之Maven(下)

极光推送中如何给多个app同时进行推送

●  Linux服务器上部署eolinker

JVM的内存结构、内存溢出、内存泄漏、内存模型你知道吗? 点击“阅读原文”,进入公众号阅读导航目录!有惊喜哦

本文分享自微信公众号 - 程序员Hotel(XIEZHIXIN_2018)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
2年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这