仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 737|回复: 18
打印 上一主题 下一主题

[学习教程] JAVA编程:JVM内存接纳实际与完成仓酷云

[复制链接]
柔情似水 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:31:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
JAVA学习必须明确这是一项投资,对于大多数的人来说,学习JAVA是为了就业,还有就是刚走向工作位置的朋友想尽快赶上工作的节奏。在上一篇《HotSpot假造机对象探秘》中,我们会商了在HotSpot里对象是怎样创立的、有如何的内存结构、怎样查找和利用。在本篇中,我们将持续切磋假造机主动内存办理体系的最主要一块本能机能:假造机怎样对出生的对象举行内存接纳。
本篇内里,一切触及到详细JVM完成的内容,仍旧默许为基于HotSpot假造机的完成,后文不再独自申明。
对象存活的判断

当一个对象不会再被利用的时分,我们会说这对象已出生。对象什么时候出生,写程序的人应该是最分明的。假如盘算机也要弄分明这件事变,就必要利用一些办法来举行对象存活判断,罕见的办法有援用计数(ReferenceCounting)有可达性剖析(ReachabilityAnalysis)两种。
援用计数算法的大抵头脑是给对象中增加一个援用计数器,每当有一个中央援用它时,计数器值就加1;当援用生效时,计数器值就减1;任什么时候刻计数器为0的对象就是不成能再被利用的。它的完成复杂,判断效力也很高,在年夜部分情形下它都是一个不错的算法,也有一些对照出名的使用案例,比方微软COM(ComponentObjectModel)手艺、利用ActionScript3的FlashPlayer、Python言语和在游戏剧本范畴失掉很多使用的Squirrel中都利用了援用计数算法举行内存办理。可是,最少Java言语内里没有选用援用计数算法来办理内存,个中最次要缘故原由是它没有一个文雅的计划往对象之间互相轮回援用的成绩:当两个对象相互援用,即便它们都没法被外界利用时,它们的援用计数器也不会为0。
很多支流程序言语中(如Java、C#、Lisp),都是利用可达性剖析来判断对象是不是存活的。这个算法的基础思绪就是经由过程一系列的称为GC根节点(GCRoots)的对象作为肇端点,从这些节点入手下手举行向下搜刮,搜刮所走过的路径成为援用链(ReferenceChain),当一个对象到GCRoots没有任何援用链相连(用图论的话来讲就是从GCRoots到这个对象不成达)时,则证实此对象是不成用的。如所示,对象object5、object6、object7固然相互有联系关系,它们的援用其实不为0,可是它们到GCRoots是不成达的,因而它们将会被判断为是可接纳的对象。

<br>
可达性剖析算法判断对象是不是可接纳
列举根节点

在Java言语内里,可作为GCRoots的节点次要在全局性的援用(比方常量或类静态属性)与实行高低文(比方栈帧中的当地变量表)中。假如要利用可达性剖析来判别内存是不是可接纳的,那剖析事情必需在一个能保证分歧性的快照中举行——这里“分歧性”的意义是全部剖析时代全部实行体系看起来就像被解冻在某个工夫点上,不成以呈现剖析过程当中,对象援用干系还在不休变更的情形,这点不满意的话剖析了局正确性就没法包管。这点也是招致GC举行时必需“StopTheWorld”的个中一个主要缘故原由,即便是号称(几近)不会产生停留的CMS搜集器中,列举根节点时也是必需要停留的。
因为今朝的支流JVM利用的都是正确式GC(这个观点在第一篇中先容过),以是当实行体系停留上去以后,其实不必要一个不漏地反省完一切实行高低文和全局的援用地位,假造机应该是有举措间接失掉哪些中央寄存着对象援用。在HotSpot的完成中,是利用一构成为OopMap的数据布局来到达这个目标,在类加载完成的时分,HotSpot就把对象内甚么偏移量上是甚么范例的数据盘算出来,在JIT编译过程当中,也会在特定的地位纪录下栈里和存放器里哪些地位是援用。如许GC在扫描时就就能够间接得知这些信息了。上面的代码清单1是HotSpotClientVM天生的一段String.hashCode()办法的当地代码,能够看到在0x026eb7a9处的call指令有OopMap纪录,它指了然EBX存放器和栈中偏移量为16的内存地区中各有一个一般对象指针(OrdinaryObjectPointer)的援用,无效局限为从call指令入手下手直到0x026eb730(指令流的肇端地位)+142(OopMap纪录的偏移量)=0x026eb7be,即hlt指令为止。
代码清单1String.hashCode()办法的编译后的当地代码
  1. [VerifiedEntryPoint]0x026eb730:mov%eax,-0x8000(%esp)…………;;ImplicitNullCheckStubslowcase0x026eb7a9:call0x026e83e0;OopMap{ebx=Oop[16]=Oopoff=142};*caload;-java.lang.String::hashCode@48(line1489);{runtime_call}0x026eb7ae:push$0x83c5c18;{external_word}0x026eb7b3:call0x026eb7b80x026eb7b8:pusha0x026eb7b9:call0x0822bec0;{runtime_call}0x026eb7be:hlt
复制代码
平安点

在OopMap的帮忙下,HotSpot能够疾速正确地地完成GCRoots列举,但一个很实际的成绩随之而来:大概招致援用干系变更,大概说OopMap内容变更的指令十分多,假如为每条指令都天生对应的OopMap,那将会必要大批的分外空间,如许GC的空间本钱将会变得很高。
实践上HotSpot也切实其实没无为每条指令都天生OopMap,后面已提到,只是在“特定的地位”纪录了这些信息,这些地位被称为平安点(Safepoint),即程序实行时并不是在一切的中央都能停留上去入手下手GC,只要在抵达平安点时才干停息。Safepoint的选定既不克不及太少以致于让GC守候工夫太长,也不克不及过于频仍以致于太过增年夜运转时的负荷。以是平安点的选定基础上是以程序“是不是具有让程序长工夫实行的特性”为尺度举行选定的——由于每条指令实行的工夫都十分长久,程序不太大概由于指令流长度太长这个缘故原由而太长工夫运转,“长工夫实行”的最分明特性就是指令序列复用,比方办法挪用、轮回跳转、非常跳转等,以是具有这些功效的指令才会发生Safepoint。
关于Sefepoint,别的一个必要思索的成绩是怎样让GC产生时,让一切线程(这里不包含实行JNI挪用的线程)都跑到比来的平安点上再停留上去。我们有两种计划可供选择:争先式中止(PreemptiveSuspension)和自动式中止(VoluntarySuspension),争先式中止不必要线程的实行代码自动往共同,在GC产生时,起首把一切线程全体中止,假如发明有线程中止的中央不在平安点上,就恢单线程,让它跑到平安点上。如今几近没有假造机完成接纳争先式中止来停息线程呼应GC事务。
而自动式中止的头脑是当GC必要中止线程的时分,不间接对线程操纵,仅仅复杂地设置一个标记,各个线程实行时自动往轮询这个标记,发明中止标记为真时就本人中止挂起。轮询标记的中央和平安点是重合的,别的再加上创立对象必要分派内存的中央。上面的代码清单2中的test指令是HotSpot天生的轮询指令,当必要停息线程时,假造机把0x160100的内存页设置为不成读,那线程实行到test指令时就会停留守候,如许一条指令便完成线程中止了。
代码清单2轮询指令
  1. 0x01b6d627:call0x01b2b210;OopMap{[60]=Oopoff=460};*invokeinterfacesize;-Client1::main@113(line23);{virtual_call}0x01b6d62c:nop;OopMap{[60]=Oopoff=461};*if_icmplt;-Client1::main@118(line23)0x01b6d62d:test%eax,0x160100;{poll}0x01b6d633:mov0x50(%esp),%esi0x01b6d637:cmp%eax,%esi
复制代码
平安地区

利用Safepoint仿佛已完善办理怎样进进GC的成绩了,但实践情形却其实不必定。Safepoint机制包管了程序实行时,在不太长的工夫内就会碰到可进进GC的Safepoint。可是,程序“不实行”的时分呢?所谓的程序不实行就是没有分派CPU工夫,典范的例子就是线程处于Sleep形态大概Blocked形态,这时候候线程没法呼应JVM的中止哀求,走到平安的中央往中止挂起,JVM也明显不太大概守候线程从头被分派CPU工夫。关于这类情形,就必要平安地区(SafeRegion)来办理。
平安地区是指在一段代码片断当中,援用干系不会产生变更。在这个地区中恣意中央入手下手GC都是平安的。我们也能够把SafeRegion看做是被扩大了的Safepoint。
在线程实行到SafeRegion内里的代码时,起首标识本人已进进了SafeRegion,那样当这段工夫里JVM要倡议GC,就不必管标识本人为SafeRegion形态的线程了。在线程要分开SafeRegion时,它要反省体系是不是已完成了根节点列举(大概是全部GC历程),假如完成了,那线程就持续实行,不然它就必需守候直到收到能够平安分开SafeRegion的旌旗灯号为止。
到这里,我们复杂先容了假造机怎样往倡议内存接纳的成绩,可是假造机怎样详细地举行内存接纳举措仍旧未触及到。由于内存接纳怎样举行是由假造机所接纳的GC搜集器所决意的,而一般假造机中常常不止有一种GC搜集器,像今朝(JDK7时期)的HotSpot内里就包括有Serial、SerialOld、ParNew、ParallelScavenge、ParallelOld、ConcurrentMarkSweep和GarbageFirst七种搜集器,鄙人一篇中,我们将以最新开始进的GarbageFirst(G1)搜集器为例,先容内存接纳的详细历程。
参考材料
本文撰写时次要参考了以下材料:


  • http://icyfenix.iteye.com/blog/1095132
  • http://xiao-feng.blogspot.com/2008/01/gc-safe-point-and-safe-region.html
  • http://rednaxelafx.iteye.com/blog/1044951

如果你学习的是市场营销,是销售,也许参加大课堂的学习会更合适,因为你的工作能力中有个基础就是搭建自己的人脉,
灵魂腐蚀 该用户已被删除
沙发
发表于 2015-1-19 11:02:38 | 只看该作者
如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
分手快乐 该用户已被删除
板凳
发表于 2015-1-23 14:37:20 | 只看该作者
吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧
第二个灵魂 该用户已被删除
地板
发表于 2015-1-31 18:09:31 | 只看该作者
一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。
5#
发表于 2015-2-2 21:52:28 | 只看该作者
Java是一种计算机编程语言,拥有跨平台、面向对java
莫相离 该用户已被删除
6#
发表于 2015-2-7 02:39:53 | 只看该作者
关于设计模式的资料,还是向大家推荐banq的网站 [url]http://www.jdon.com/[/url],他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。
飘飘悠悠 该用户已被删除
7#
发表于 2015-2-13 13:14:40 | 只看该作者
还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。
变相怪杰 该用户已被删除
8#
发表于 2015-2-26 20:57:09 | 只看该作者
是一种为 Internet发展的计算机语言
透明 该用户已被删除
9#
发表于 2015-2-27 02:21:26 | 只看该作者
是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言
因胸联盟 该用户已被删除
10#
发表于 2015-2-27 07:10:06 | 只看该作者
应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展
小女巫 该用户已被删除
11#
发表于 2015-2-28 09:21:42 | 只看该作者
应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展
精灵巫婆 该用户已被删除
12#
发表于 2015-3-7 03:14:59 | 只看该作者
Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。
深爱那片海 该用户已被删除
13#
发表于 2015-3-7 04:09:57 | 只看该作者
你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。
若相依 该用户已被删除
14#
发表于 2015-3-7 08:44:42 | 只看该作者
你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。
再现理想 该用户已被删除
15#
发表于 2015-3-11 19:51:50 | 只看该作者
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
老尸 该用户已被删除
16#
发表于 2015-3-17 17:09:52 | 只看该作者
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
乐观 该用户已被删除
17#
发表于 2015-3-24 13:05:16 | 只看该作者
是一种将安全性(Security)列为第一优先考虑的语言
谁可相欹 该用户已被删除
18#
发表于 2015-4-2 19:45:00 | 只看该作者
接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。
爱飞 该用户已被删除
19#
发表于 2015-4-11 00:10:02 | 只看该作者
让你能够真正掌握接口或抽象类的应用,从而在原来的Java语言基础上跃进一步,更重要的是,设计模式反复向你强调一个宗旨:要让你的程序尽可能的可重用。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-24 00:44

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表