当前位置: 首页 > news >正文

做网站月入过万的经验/关键字排名查询

做网站月入过万的经验,关键字排名查询,建筑安装公司,克拉玛依燃气公司主页深入理解Java虚拟机 读书笔记 Java的内存区域 程序计数器,就是操作系统里面的PC指针,指向当前执行的代码的地址,线程私有。Java虚拟机栈,线程私有,每个线程对应一个栈,每个方法对应一个栈帧,一…

深入理解Java虚拟机 读书笔记

Java虚拟机运行时数据区

Java的内存区域

  • 程序计数器,就是操作系统里面的PC指针,指向当前执行的代码的地址,线程私有。
  • Java虚拟机栈,线程私有,每个线程对应一个栈,每个方法对应一个栈帧,一个方法的执行就是出栈入栈的过程。
  • Java堆,线程共享的,用于存放对象的实例,垃圾收集管理的主要区域,大部分GC采用分代收集法,所以GC区分为新生代和老年代。(更详细的垃圾回收部分后面会讲)
  • 方法区,所有线程共享的,存储已经被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等。
  • 运行时常量池,方法区的一部分,编译期生成的各种字面量和符号引用。
  • 直接内存,NIO,基于通道与缓冲区的IO方式,使用native函数库直接分配堆外内存,通过Java堆中的DirectByteBuffer作为这块内存的引用进行操作,避免了在Java堆和Native堆中来回的复制数据。

Java对象的创建

根据new关键字后面的参数定位到常量池中的符号引用,然后检查类加载没,没加载就加载了,加载后就知道对象要分配的空间大小了,然后根据要分配的空间大小从Java堆上划出来一块。如果Java堆是规整的,就是使用“指针碰撞”法,分配内存就把指针往后移一下。如果Java堆是不规整的,空闲的和使用的交错放置的,就使用“空闲列表”法。使用哪种方法取决于GC,如果GC带压缩整理,垃圾回收的时候能顺便把内存归拢起来就指针碰撞法,否则就空闲列表。
同时,对象创建的过程在并发情况下并不是线程安全的,如果一个指针还没来得及挪,另一个就挪好了,然后这个指针记录了错误的位置,这种情况就GG了。所以有两种解决的办法,其实本质上都是一种,就是同步锁定(CAS和失败重试详见http://blog.csdn.net/hsuxu/article/details/9467651),第一种是每一次new的时候都进行同步锁定。第二种是搞了个本地线程分配缓冲(Thread Local Allocation Buffer, TLAB),每个线程有一小块缓冲,这样一般情况下分配内存的时候可以直接从缓冲取缓冲一下,只有在TLAB用完并重新分配的时候同步一下。其实本质上第二种方法也是同步,只不过减少了同步使用的次数。
内存划出去以后,再执行设置对象的类的元信息,哈希码,GC分代年龄等信息,放到对象头(Object Header)中。最后执行对象的构造函数,香喷喷热腾腾的对象就做好了。

对象的内存布局

对象头,实例数据,对齐补充
对象头两部分,一部分是对象自身运行的数据,Hash码、GC分代年龄、锁状态标志。。。“Mark Word”。另一部分是指向类元数据的指针,表明它是哪个类的实例,如果是数组,还会有一个数组长度的数据。
实例数据,就是干货,就是java里面写的那些东西,无论是父类继承下来的,还是子类定义的,按照虚拟机分配策略参数和java代码里面的定义顺序排序。
对齐补充,HotSpot对象的起始地址规定是8字节的整数倍,所以对象的大小必须是8字节的整数倍,所以需要对齐补充。

对象的访问定位

Java程序是通过栈上的reference数据来操作堆上的具体对象,由reference定位访问到堆上对象的方法取决于虚拟机的设定,主流的访问方式有使用句柄和直接指针两种。
通过句柄访问对象
使用句柄需要在Java堆中划出来一块内存放句柄池,然后通过句柄池访问实例和方法区中的对象类型数据。
通过直接指针访问对象
直接指针访问就是直接指到Java堆对象实例所在的位置,然后对象实例所在的位置会有个指针指向方法区的对象类型数据。
使用句柄的好处是方便归拢,比如垃圾回收时经常会移动对象,只需要改变句柄中的实例数据的指针即可,reference本身不需要修改。
使用直接指针的好处就是一个字“快”,速度更快,没有那么多屁事,不需要绕弯子,reference直接怼到对象实际的位置上,对象访问那么频繁,这样可以大大的提速。Sun HotSpot就是用的这种方式。

实战之——OutOfMemoryError异常(传说中的OOM)

除了程序计数器以外,其它的几个虚拟机内存运行时区域都有可能发生OOM

Java堆溢出

只要不断的创建对象,并且保证GC Roots到对象之间有可达路径避免垃圾回收,那么对象数量到达最大堆的容量限制之后就会产生内存溢出异常。
示例代码:

/*** * VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError* @author DC**/
public class HeapOOM {static class OOMObject{}public static void main(String[] args) {List<OOMObject> list = new ArrayList<OOMObject>();while(true){list.add(new OOMObject());}}
}

使用内存映像分析工具,首先分析内存中的是否是必要的,也就是分清楚到底是内存泄露(Memory Leak)还是内存溢出(Memory Overflow)
如果是内存泄露,可以通过工具查看泄露对象到GC Roots的引用链。
如果不是内存泄露,也就是内存中的对象都必须活着,那么就是虚拟机参数设置小了,那么就修改参数(-Xms和-Xmx)

JVM对那些没有根引用的对象进行来及回收,也就是无法从根对象中追述的对象。

JVM垃圾回收的根对象的范围有以下几种:

1、栈中引用的对象,引用是在栈帧中的本地变量表中的,真正的对象在堆中

2、方法区perm中的类静态属性引用的对象,以及常量引用的对象

3、本地方法栈中JNI(Native方法)的引用的对象

虚拟机栈和本地方法栈溢出

虚拟机请求的栈深度大于虚拟机所允许的最大深度,抛出StackOverflowError异常。
扩展栈时没有申请到足够大的内存空间,则抛出OutOfMemoryError异常。
单线程模式下,无论是栈帧太大还是虚拟机栈容量太小,一般都只会抛出StackOverflowError异常。
多线程模式下,会产生OutOfMemoryError异常,为每个线程分配的栈越大越容易异常,因为除去堆区和方法区的部分如果不够线程瓜分,就会内存溢出,跟栈没关系。

方法区和运行时常量池溢出

方法区是用来存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。
CGLIB(Code Generation Library)是一个代码生成的库,Spring的AOP和Hibernate的OR Mapping都是通过它来实现的。它可以实现动态的代理,比如AOP就是通过它来实现的。JDK自带的代理需要代理的对象实现一个接口,而使用了CGLIB的AOP就不需要这些东西,因为它的底层是一个小而快的字节码处理框架ASM,使用它可以把原来的class封装起来实现方法的拦截。

http://www.lbrq.cn/news/1109467.html

相关文章:

  • 无锡地区网站制作公司排名/广州网站优化页面
  • 顺德品牌网站建设信息/怎样去推广自己的网店
  • 浦东新区网站优化公司/关键词怎么选择技巧
  • seo建站外贸/谷歌搜索引擎首页
  • 查找做像册的网站/杭州网络推广
  • 淘宝客网站建设教程视频/seo网站优化软件价格
  • 云主机搭建多个网站/seo培训学什么
  • 网站开发建设培训/百度爱企查电话人工服务总部
  • 晋中做网站公司/宁波seo推广哪家好
  • 不用代码可以做网站设计吗/广告投放平台系统
  • 桥西企业做网站/seo网站排名优化工具
  • 辽宁省建设局网站/深圳知名seo公司
  • 联谊会建设网站/网络广告策划方案
  • 网站建设方案书人员资金安排/百度网站链接
  • 卫生系统网站的建设和维护/网站收录服务
  • 做牙科设计的网站/互联网广告投放平台加盟
  • 做外汇应该看哪一家网站/化妆品营销推广方案
  • 如何彻底清除网站的网页木马/视频广告联盟平台
  • 百度云平台建设网站/优化软件下载
  • 如何做体育彩票网站/企业培训权威机构
  • 网站开发国外研究状况/太原seo推广外包
  • 做吉祥物的网站/百度推广计划
  • 百度站长工具有哪些/seo优化公司
  • 查询做导员的网站/工作手机
  • wordpress降低版本/怎样优化网站排名靠前
  • 测试网站免费空间/如何推广公司网站
  • 医院网站党支部机构建设/自媒体平台
  • 民权平台网站建设/沈阳优化网站公司
  • 建立个人网站需要什么/网页制作成品模板网站
  • 网站快照是自己做的吗/滨州seo招聘
  • 【逻辑回归】MAP - Charting Student Math Misunderstandings
  • cartorgapher的编译与运行
  • Vue (Official) v3.0.2 新特性 为非类npm环境引入 globalTypesPath 选项
  • 【C++详解】STL-stack、queue的模拟实现,容器适配器,deque双端队列介绍
  • 时序数据库选型指南 —— 为什么选择 Apache IoTDB?
  • kimi-k2-api使用示例