关于这个问题好像查的人还不少,网上的说法也不是很统一,我直接在<深入理解Java虚拟机:JVM高级特性与最佳实践(第3版) 周志明>这本书中来给大家找到答案吧

在Java技术体系里面, 固定可作为GC Roots的对象包括以下几种:
·在虚拟机栈(栈帧中的本地变量表) 中引用的对象, 譬如各个线程被调用的方法堆栈中使用到的参数、 局部变量、 临时变量等。
·在方法区中类静态属性引用的对象, 譬如Java类的引用类型静态变量。
·在方法区中常量引用的对象, 譬如字符串常量池(String Table) 里的引用。·在本地方法栈中JNI(即通常所说的Native方法) 引用的象。
·Java虚拟机内部的引用, 如基本数据类型对应的Class对象, 一些常驻的异常对象(比如NullPointExcepiton、 OutOfMemoryError) 等, 还有系统类加载器。
·所有被同步锁(synchronized关键字) 持有的对象。
·反映Java虚拟机内部情况的JMXBean、 JVMTI中注册的回调、 本地代码缓存等。
除了这些固定的GC Roots集合以外, 根据用户所选用的垃圾收集器以及当前回收的内存区域不同, 还可以有其他对象“临时性”地加入, 共同构成完整GC Roots集合。 譬如后文将会提到的分代收集和局部回收(Partial GC) , 如果只针对Java堆中某一块区域发起垃圾收集(如最典型的只针对新生代的垃圾收集) , 必须考虑到内存区域是虚拟机自己的实现细节(在用户视角里任何内存区域都是不可见的) , 更不是孤立封闭的, 所以某个区域里的对象完全有可能被位于堆中其他区域的对象所引用, 这时候就需要将这些关联区域的对象也一并加入GC Roots集合中去, 才能保证可达性分析的正确性

上面这段话是书中的原话
文章中说的可达性分析(Reachability Analysis) 算法是用来判定对象是否存活的
希望书中的话可以帮助到大家,我们遇到问题的时候要多看看,尽量不要只看一个人的博客而不再去看别人的博客。如果那个人写错了,那这种错误的理解会影响到我们。关于jvm大家可以读读这本书的,还是很不错的。