java vs c++
java:自动处理
java是有人帮你回收
c++:手动处理,会有很多问题
c++比较精确,立马回收
没有一根线连着它的时候,它就是垃圾
JAVA程序从main方法开始执行,,一个main方法会启动一个线程,这个线程里面会有线程栈,里面会有main栈帧。从这个main里面开始的这些对象都是我们的根对象,这个main方法调用了别的方法,那别的方法也是我们引用的,都是有用的对象,但是从main开始这个线程栈帧里面这些个叫做根对象,另外一个叫静态变量,一个class有一个静态的变量。load到内存后马上对静态变量进行初始化,所以静态变量访问的到的对象这个叫根对象。还有常量池指的是如果这个class会用到其他的class的那个类的对象,这些事根对象。JNI指的是如果你调用了c和c++写的那些本地方法所用到的那些个类或者对象。
根可达算法:是从根上对象开始搜索
线程栈变量:一个main方法开始运行,main线程栈中的变量调用了其他方法,main栈中的方法访问到的对象叫根对象
静态变量:T.class对静态变量初始化能过访问到的对象叫做根对象
常量池:如果一个class能够用到其他的class的对象叫做根对象
JIN:如果调用的了本地方法运用到本地的对象叫做根对象
根对象:当一个程序马上启动的时候需要的对象叫做根对象
算法相对简单
存活对象比较多的情况下效率较高
Mark-Sweep:标记,清除。就是把它标记出来,然后清除。
两遍扫描,效率偏低容易产生碎片
适用于存活对象较少的情况
只扫描一次,效率提高没有碎片
空间浪费
移动复制对象,需要调整对象引用
Copying:就是把内存一分为二,分开之后把有用的拷贝到下面绿色区域,拷贝完后上面全部清掉。
不会产生碎片,方便对象分配
不会产生内存减半
Mark-Compact;就是把所有的东西整理的过程,清理的过程同时压缩到头上去。回收之前,有用的全往前面走,剩下的大块空间就全部清出来了。
扫描两次
需要移动对象,效率偏低
这个分代算法和垃圾回收器是有关系的,分代这件事由于JVM分了这么多年,分代是存在于ZGC之前的所有垃圾回收器都是分代算法,除了G1之外的其他垃圾回收器不仅在逻辑上,在物理上也是分代的。
新生代分为:
eden(伊甸)默认比例8:是我们刚刚new出来对象之后往里扔的那块区域
survivor默认比例1:是回收一次之后跑到这个区域,这里面由于装的对象不同,所以采取的算法不同
survicor默认比例1:新生代存活对象特别少,死去对象特别多的算法是Copying
old老年代:
老年代活着的对象特别多适用于:Mark Compact或Mark Sweep算法
这个对象到底是怎样进行GC过程的:一个对象产生后首先进行栈上分配,栈上如果分配不下会进入伊甸区,伊甸区经过一次垃圾回收之后进入survivor区,survivor区在经过一次垃圾回收之后又进入另一个survivor,与此同时伊甸区的某些对象也跟着进入另外一个survivor,什么时候年龄够了会进入old区,这是整个对象的一个逻辑上的移动过程。
stack:s0-s1之间的复制年龄超过限制时,进入old区,通过参数:-XX:MaxTenuringThreshold配置。
栈上分配要比堆上分配要快,在站上分配不下,它会优先进行本地分配
在伊甸区好多线程都往里头分配对象,分配对象的时候你这个线程一定会进行空间征用,谁抢到算谁的。多线程的同步效率就会低,所以设计了这么一个机制叫做TLAB
java 回车//查看java参数
java的参数
java -XX:printFlagsFinal -version//打印所有参数
JDK诞生之后第一个垃圾回收器就是Serial和Serial Old。
常见的垃圾回收器组合有三种(Serial+Serial Old)、(Parallel Scavenge+Parallel Old)、(ParNew+CMS)
当工作的时候,所有工作线程全部停止,当工作的时候断开的线程则是垃圾,如果突然加入Serial则停止,进行清理垃圾。
这个用在老年代,他用的是mark-sweep的算法,用的也是单线程。
如果你在JVM没有做任何调优的话,默认的就是Parallel Scavenge和Parallel Old简称PS+PO。
和Parallel Scavenge没什么区别,就是做了一些增强,便于和CMS一起使用。
他回收垃圾的线程和工作线程同时进行,叫做concurrent mark sweep(concurrent 并发)。
原文:https://www.cnblogs.com/striver20/p/13763536.html