メモリ構造とガベージコレクションアルゴリズム

JAVAはまた、あなたがJVMを勉強しなければならない場合は、その後、あなたはこれが唯一のタイルのプログラマのツールとなり得る3年後、しきい値2年近く、会社のリーダーが言ったとJAVAを行って、3年ですか。これらの日JVMを解決するの辞任と一致?

 

JVMは、Java仮想マシン(Java仮想マシン)の頭文字であるが、また、JVMの仮想マシンを意味し、コンピュータのうちフィクションで、当社の実際のコンピュータのさまざまなコンピュータ機能をシミュレートするようなことまでしました。

JVMは、メモリを解放するとき、心配する必要はもはやJAVAに従事し、存在しないので、それはC ++プログラマのためのそのように少ないメモリのビットと憂鬱ではありません、そのためにあなたはこれらの事が行われて置く助けるために、JVM仮想マシンです、その後、JVM JAVA、私たちはそれを言います!

 

のは、百度のビューの文書のポイントの前に、上記のカップル、メソッド領域、ヒープ、スタック、カウンタを言って、それのJVMモデルを見てみましょう。、非常に難しい受け入れることはなかったし、JVMの深い理解の本を読んで、それは少しの経験と見なすことができます。

 

JVMは、JVMランタイムデータ領域は、いくつかの異なる領域に分割されますブックの深い理解は、方法ゾーン(方法エリア)、仮想スタックマシン(VMスタック)、ネイティブメソッドスタック(ネイティブメソッドスタック)がありますヒープ(ヒープ)、プログラムカウンタ(プログラムカウンタレジスタ)は、以下の図の本です。

 

一つ一つを説明してみましょう:私はプログラムカウンタ(プログラムカウンタレジスタ)についてお話しましょう:プログラムカウンタは、実際には次の命令が、我々は命令を実行するとき、最初の命令は彼の店の場所を知っている場所のアドレスを格納するために使用して、さ命令にもたらされるレジスタが命令を取得することで、その後、プログラムカウンタのアドレスに格納され、実行に1ずつ増加し、このサイクルのようにされ、プログラムカウンタこの小さなメモリ領域は、「スレッド・プライベート・メモリー」です。

 

なぜそれがプライベートで?JVMはマルチスレッドの仮想マシンがプロセッサの割り当ての実行時間は、発音するのは非常に困難であることを、実装する方法の交互に切り替えるスレッドによってスイッチングされている書籍の深い理解は、実際には、それは、同じプロセッサであります時間、実行命令の唯一のスレッドが、時間が、平衡ではないかもしれない、Bのスレッドが移動するための第二分のスレッドの最初の分実行することができるが、その後、スイッチバックを確保するためにも一致する必要がある場合、各無影響ことを確実にするために、格納する独立したプログラムカウンタのスレッド独立した存在、が存在するであろう。そこで彼は、「スレッド・プライベート・メモリー」です。

 

プログラムカウンタのいくつかの機能があります。

スレッドは、Javaメソッドを実行している場合•、カウンタが実行されている仮想マシンのバイトコード命令のアドレスを記録します。

•あなたがネイティブメソッドを実行している場合は、カウンタ値が(未定義)は空です。

•このメモリ領域は、地域のOutOfMemoryError Java仮想マシン仕様でどのような状況のために用意されていませ唯一のものです。

 

それぞれ、これら三つの言葉を説明し、これはJava仮想マシンの言葉の深い理解があり、最初の文は言っていない、非常に簡単、それは言われているようだ、第2文

 

このカウンタは、バイトコード命令のアドレスを記録しますが、ネイティブ(ローカル方式)されているので、例えば、(のSystem.currentTimeMillis())彼はCによって達成され、システムがにコンパイルする必要はありませんする必要性から直接呼び出しを指示しますバイトコード命令の実行は、その後、プログラムカウンタの同等は、しかし、それはその後、彼は確かに、カウンタの値が空であるだろう、という記録を持っていません。

 

3番目の文は、我々は短いコードをコンパイルしようとした後、見にコンパイルすることができます

つまり、このように実際にあります

パブリッククラスTest {パブリックint型試験(){int型A = 10; // 0 ...... INT B = 20; // 3 ....... INT C = 30; // 6 ... ...リターン(A + B)* C; // 11 .... 13 .... 14 ...}}の演算を行います

上面的0,2,3,5,6,8....就是指令的偏移地址bipush就是入栈指令, 在执行到test方法的时候,线程就会创建对应的程序计数器在计数器中放0,2,3,5,6,8....这些指令地址,所以计数器里改变的不是内存的大小,它也就没有溢出了。

 

下面我们再来说一下:JAVA虚拟机栈(VM Stack)

线程私有,生命周期和线程一样,这个虚拟机栈描述的是JAVA方法执行的内存模型,用于存局部变量,操作数栈,方法出口等信息的,上面那个bipush就是入栈指令,在这里最需要注意的就是他存放的是什么数据.局部变量里面放的就是那些我们所知道的基本的数据类型,对象引用的话那就是一个地址。

 

在虚拟机规范里面还说,他的2个异常状况:

•一个是StackOverflowError异常,栈内存溢出,这肯定很容易理解,就是栈的内存不够,你的请求线程太大。(固定长度的栈)

•如果说在动态扩展的过程中,申请的长度还是不够,那么会抛出另外一个异常OutOfMemoryError异常。

 

 

3.本地方法栈(Native Method Stack) :

它和虚拟机栈很类似,区别就在于虚拟机栈执行的是JAVA方法,但是本地方法栈则是Native方法,其他的没啥不同就连抛出异常都一样的。

 

4.JAVA堆(heap) 在JVM一书中也有提到,Heap是在JAVA虚拟机中内存占用最大的一个地方,也是所有线程共享的一个内存区域,堆内存中主要就是用于存放对象实例的。

 

几乎是所有的对象实例都在这里分配内存,JAVA堆是垃圾收集器管理的主要区域,那么现在重点来了,面试中问到最多的垃圾回收机制接下来就要仔细说说了。

 

内存回收,现在都是进行的分代算法,堆中也是,新生代,老年代,而且两种垃圾回收机制是采用的不同的回收机制的,在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

 

而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用"标记-清理"或"标记-压缩"算法来进行回收,说回收机制先看看heap的分区(这个from和to 并不是绝对的,看对象处在哪个位置,GC的次数不一样之后,那from和to会有相应转变)

分区一目了然,下面研究一下算法实现吧

Minor GC:GC新生代,

Full GC:老年代GC,

因为新生代中对象的存活率比较低,所以一般采用复制算法,老年代的存活率一般比较高,一般使用”标记-清理”或者”标记-整理”算法进行回收。

 

看了有几天才明白啥意思,我说说我自己的见解吧,还是画图吧,

Minor GC:

我们每次new对象的时候都会先在新生代的Enden区放着也就是最开始 是这样子的

 

然后在Enden用完的时候里面会出现待回收的

 

 

然后就来了把存活的对象复制放到Survior1(from)中,待回收的等待给他回收掉 就是这样的

 

 

然后把Enden区清空回收掉

 

 

这样的话 第一次GC就完成了,下面再往下走

当Enden充满的时候就会再次GC

先是这个样子的

 

 

然后会把 Enden和Survoir1中的内容复制到Survior中,

 

 

然后就会把Enden和Survior进行回收

 

 

然后从Enden中过去的就相当于次数少的,而从Survior1中过去的就相当于移动了2次

 

 

这样新生代的GC就执行了2次了,

当Enden再次被使用完成的时候,就会从Survior2复制到Survior1中,

接下来是连图

 

经过回收之后Surior1就变了,1对象是从Enden直接复制过来的,2对象是Enden-->Survior2-->Survior1 ,3对象则是从Enden-->Surivior1-->Survior2-->Survior1 复制过来的,这样一步一步的执行下去的时候,就是新生代的GC。

 

既然这样,那为什么还会存在老年代呢?其实如果GC在执行的时候有些对象一直没有被回收,那么他移动次数就会无限的累计,每次从Surior(from)到Surior(to)的过程中就相当于又增加了一次移动,当他达到一定的次数的时候(默认是15),就会移动到老年代里了,所以不存在不会被回收的对象,但是这个次数可以设置的,

-XX:MaxTenuringThreshold

就类似这样子

其实上边的这只是一种情况,还有就是如果对象太大,存不下,那就直接会进入老年代。

还有那种默认就是长期活着的也会进入老年代,

而且这种复制算法的垃圾回收机制是比较浪费内存的,每次都会有一块内存区是闲着不干活的,但是优点很明显,简单高效

以上就是GC中垃圾回收中的新生代复制算法解析,新生代的Minor GC也算是知道了不少东西了,以上就是一些个人的见解,图比较清晰,容易理解,有不对的地方希望能够各位同行指点一下。

 


 

Java 极客技术公众号,是由一群热爱 Java 开发的技术人组建成立,专注分享原创、高质量的 Java 文章。如果您觉得我们的文章还不错,请帮忙赞赏、在看、转发支持,鼓励我们分享出更好的文章。

关注公众号,大家可以在公众号后台回复“博客园”,免费获得作者 Java 知识体系/面试必看资料。 

 

おすすめ

転載: www.cnblogs.com/justdojava/p/11198694.html