java垃圾回收那点事究竟有多少GC
发布时间:2025-05-20 10:29:48 发布人:远客网络
一、java垃圾回收那点事究竟有多少GC
1.Java中finalize()的作用一主要是清理那些对象(并非使用new)获得了一块“特殊”的内存区域。程序员可以用finalize()来操作。程序员都了解初始化的重要性,但常常会忘记同样也重要的清理工作。毕竟,谁需要清理一个int呢?但在使用程序库时,把一个对象用完后就“弃之不顾”的做法并非总是安全的。当然,Java有垃圾回收器负责回收无用对象占据的内存资源。但也有特殊情况:假定你的对象(并非使用new)获得了一块“特殊”的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道该如何释放该对象的这块“特殊”内存区域,为了应对这种情况,java允许在类中定义一个名为finalize()的方法。它的工作原理“假定”是这样的:一旦垃圾回收器准备好释放对象占用的存储孔家,将首先调用其finalize()的方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。所以要是你打算用finalize(),就能在垃圾回收时刻做一些重要的清理工作。注意这里的finalize()并不是C++里的析构.在C++中,对象一定会被销毁,而在Java里的对象却并非总是被垃圾回收(1.对象可能不被垃圾回收;2.垃圾回收并并不等于“析构”)。
2.垃圾回收只与内存有关。也就是说,使用垃圾回收器的唯一原因是为了回收程序不再使用的内存。所以对于与垃圾回收有关的任何行为来说(尤其是finalize()方法),它们也必须同内存及其回收有关。但这是否意味着要是对象中含有其他对象,finalize()就应该明确释放那些对象呢?不,无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。不过,java中一切皆为对象,那这种特殊情况是怎么回事呢?由于在分配内存时可能采用了类似C语言中的做法,而非java中的通常做法。这种情况主要发生在使用“本地方法”的情况下,本地方法是一种在Java中调用非Java代码的方式。在非java代码中,也许会调用C的malloc()函数系列来分配存储空间,而且除非了free()函数
“引用记数(reference counting)”是一种简单但速度很慢的垃圾回收技术。每个对象都含有一个引用记数器,当有引用连接至对象时,引用计数加1。当引用离开作用域或被置为null时,引用计数减1。虽然管理引用记数的开销不大,但需要在整个程序生命周期中持续地开销。垃圾回收器会在含有全部对象的列表上遍历,当发现某个对象的引用计数为0时,就释放其占用的空间。这种方法有个缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为零”的情况。对垃圾回收器而言,定位这样存在交互引用的对象组所需的工作量极大。引用记数常用来说明垃圾收集的工作方式,似乎从未被应用于任何一种Java虚拟机实现中。
二、java要学到什么程度才能胜任工作
Java作为面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用的两个特征。也正是由于其简单性、可移植性、安全性、动态性等特点,Java成为了服务器端的顶梁柱,保护着网站的一方安全。既然Java语言这么优秀,那么,如果想要以java去找工作,一个Java初学者要学多少Java知识,才能找到第一份Java工作呢?
首先我们先要了解一下在工作过程中需要用到的java基础知识有哪些:
1、synchronizedstatic修饰类和方法有什么区别?
2、HashMap的原理,底层数据结构,rehash的过程,指针碰撞问题?
3、HashMap的线程安全问题,为什么会产生这样的线程安全问题?
3、ConcurrentHashMap的数据结构,底层原理,put和get是否线程安全?
5、JavaIO的一些内容,包括NIO,BIO等?
如果以上的基础知识大家能够运用自如,也就是说工作过程中做一些基本的事情还是可以的,但是是远远不过的,如果想要在工作过程中有自己的一席之地还是要学会以下几点,才能够勉强进入企业工作。
一、Java线程池的构造方法,里面参数的含义,以及原理:
1、volatile和ThreadLocal解决了什么问题
3、Java虚拟机的构成,以及一个Java对象的生命周期,还有堆栈和方法区中存储的内容
4、JVM的GC过程,包括一些实际问题的分析,比如说明一个现象,让你分析可能是什么原因会导致这样的问题,应该如何对JVM参数进行调优
5、synchronized和Lock的区别,以及底层实现原理
8、jmap,jstat,jstack等的使用场景,MAT等
10、CountDownLatch、CyclicBarrier和Semaphore等
二、数据库:这里的数据库包含两种,一种一般是MySQL,另外是NoSql数据库,包括Redis、MongoDB等。一般会问的问题有:
1、innerjoin和leftjoin等的区别
2、SQL调优,explain,profile等
5、数据库的事务隔离级别,以及他们分别能解决什么问题
10最左前缀索引,索引的数据结构,聚簇索引等(这块还没搞明白)
因为spring是我们常用的框架,所以这块的内容会问的比较多,也会比较细。
3、Spring是如何解决Bean的循环引用问题的
4、AOP的两种实现方式,以及两者的区别(这里其实使用了动态代理,具体动态代理分为两种,一种是JDK的动态代理,主要使用的是JDK的反射,还有一种是CGLib,两者区别可以自己搜索,文章比较多)
MyBatis:这块问到的比较简单些:
Dubbo:因为平时自己用到了Dubbo,所以这块会有问到:
这块的内容是基础,如果面试官怀疑你的能力,一般一会问到这部分内容,比如树的遍历、快速排序等。
一般会问一些命令的使用,然后会举一个实际的场景,让你用命令去排查问题,这块自己不是很熟,需要尽快加强。
随着java的普及,懂Java的人越来越多,企业也会对求职者提出更高的要求,他们更希望招聘一些马上能上手工作的,所以倾向于招聘一些有项目开发经验的,这也是为什么那么多的大学计算机专业毕业的大学生找不到工作的原因,所以越来越多的大学生才会选择毕业前后参加一些专业的Java培训班来增加实战经验。只有增加自我实力才能出于不败之地。
三、java垃圾收集器收集标准
1、Java垃圾收集器与类的finalize()方法总结
2、1.垃圾收集器的工作目标是回收已经无用的对象的内存空间,从而避免内存渗漏体的产生,节省内存资源,避免程序代码的崩溃。
3、2.垃圾收集器判断一个对象的内存空间是否无用的标准是:如果该对象不能再被程序中任何一个"活动的部分"所引用,此时我们就说,该对象的内存空间已经无用。所谓"活动的部分",是指程序中某部分参与程序的调用,正在执行过程中,尚未执行完毕。
4、3.垃圾收集器线程虽然是作为低优先级的线程运行,但在系统可用内存量过低的时候,它可能会突发地执行来挽救内存资源。当然其执行与否也是不可预知的。
5、4.垃圾收集器不可以被强制执行,但程序员可以通过调用System. gc方法来建议执行垃圾收集器。
6、5.不能保证一个无用的对象一定会被垃圾收集器收集,也不能保证垃圾收集器在一段Java语言代码中一定会执行。因此在程序执行过程中被分配出去的内存空间可能会一直保留到该程序执行完毕,除非该空间被重新分配或被其他方法回收。由此可见,完全彻底地根绝内存渗漏体的产生也是不可能的。但是请不要忘记,Java的垃圾收集器毕竟使程序员从手工回收内存空间的繁重工作中解脱了出来。设想一个程序员要用C或C++来编写一段10万行语句的代码,那么他一定会充分体会到Java的垃圾收集器的优点!
7、6.同样没有办法预知在一组均符合垃圾收集器收集标准的对象中,哪一个会被首先收集。
8、7.循环引用对象不会影响其被垃圾收集器收集。
9、8.可以通过将对象的引用变量(reference variables,即句柄handles)初始化为null值,来暗示垃圾收集器来收集该对象。但此时,如果该对象连接有事件监听器(典型的 AWT组件),那它还是不可以被收集。所以在设一个引用变量为null值之前,应注意该引用变量指向的对象是否被监听,若有,要首先除去监听器,然后才可以赋空值。
10、9.每一个对象都有一个finalize()方法,这个方法是从Object类继承来的。
11、10.finalize()方法用来回收内存以外的系统资源,就像是文件处理器和网络连接器。该方法的调用顺序和用来调用该方法的对象的创建顺序是无关的。换句话说,书写程序时该方法的顺序和方法的实际调用顺序是不相干的。请注意这只是finalize()方法的特点。
12、11.每个对象只能调用finalize()方法一次。如果在finalize()方法执行时产生异常(exception),则该对象仍可以被垃圾收集器收集。
13、12.垃圾收集器跟踪每一个对象,收集那些不可到达的对象(即该对象没有被程序的任何"活的部分"所调用),回收其占有的内存空间。但在进行垃圾收集的时候,垃圾收集器会调用finalize()方法,通过让其他对象知道它的存在,而使不可到达的对象再次"复苏"为可到达的对象。既然每个对象只能调用一次finalize()方法,所以每个对象也只可能"复苏"一次。
14、13.finalize()方法可以明确地被调用,但它却不能进行垃圾收集。
15、14.finalize()方法可以被重载(overload),但只有具备初始的finalize()方法特点的方法才可以被垃圾收集器调用。
16、15.子类的finalize()方法可以明确地调用父类的finalize()方法,作为该子类对象的最后一次适当的操作。但Java编译器却不认为这是一次覆盖操作(overriding),所以也不会对其调用进行检查。
17、16.当finalize()方法尚未被调用时,System. runFinalization()方法可以用来调用finalize()方法,并实现相同的效果,对无用对象进行垃圾收集。
18、17.当一个方法执行完毕,其中的局部变量就会超出使用范围,此时可以被当作垃圾收集,但以后每当该方法再次被调用时,其中的局部变量便会被重新创建。
19、18.Java语言使用了一种"标记交换区的垃圾收集算法"。该算法会遍历程序中每一个对象的句柄,为被引用的对象做标记,然后回收尚未做标记的对象。所谓遍历可以简单地理解为"检查每一个"。
20、19.Java语言允许程序员为任何方法添加finalize()方法,该方法会在垃圾收集器交换回收对象之前被调用。但不要过分依赖该方法对系统资源进行回收和再利用,因为该方法调用后的执行结果是不可预知的。通过以上对垃圾收集器特点的了解,你应该可以明确垃圾收集器的作用,和垃圾收集器判断一块内存空间是否无用的标准。简单地说,当你为一个对象赋值为null并且重新定向了该对象的引用者,此时该对象就符合垃圾收集器的收集标准。