java和c++最典型的区别就是内存的管理方式不同,java的内存管理是通过虚拟机来实现的,通过垃圾回收器释放内存。c++通常情况下是通过程序员手动释放。为什么说是通常呢?在c++有智能指针,通过引用计数方式释放内存。
在c++11中,智能指针分为强引用指针、强指针引用和弱引用指针。强引用指针每个指针独享一块内存区域、强指针引用引用是大家共享一块堆内存,弱引用指针很多时候在配合强指针引用使用,动态的知道所指的对象是否活着。还有就是解决循环引用的问题。java的引用类型和c++的智能指针有一定相似的地方。
java中的引用类型分为强引用、弱引用、虚引用和软引用四种。
强引用
Object object=new Object();
这是java通常的创建对象的方式,jvm不会回收强引用所引用的对象,即使内存不足,发生OOM错误。
如果将object=null;那么在下次触发gc的时候我们new出来的这个对象就会被销毁。
弱引用
无论内存是否充足,在进行垃圾回收的时候,jvm都会将弱引用所引用的对象回收
String str=new String("hello world");
WeakReference<String> sf = new WeakReference<String>(str);
str=null;
System.out.println(sf.get());
System.gc();
System.out.println(sf.get());
首先会输出hello world,然后输出null。在进行垃圾回收的时候,若引用关联的对象会被回收。
软引用
如果一个对象被软引用所引用,那么在内存不足的情况下,会被jvm回收。
String str=new String("hello world");
SoftReference<String>sr=new SoftReference<String>(str);
List<Object>data=new ArrayList<>();
while (true){
System.out.println(sr.get());
data.add(new String[1024]);
}
这段程序刚开始输出的是hello world,一段时间后输出null,最后发生OOM错误退出。jvm参数设置不同,效果有所区别。当内存不够时,jvm会对软引用进行回收。
虚引用
如果一个引用和虚引用关联,则和没有引用关联一样,jvm会将其回收。虚引用需要和引用队列联合使用,需要将虚引用加入引用队列中,如果虚引用已加入引用队列,那么会被虚引用引用的对象将会被回收。
ReferenceQueue<String>queue=new ReferenceQueue<>();
String str=new String("hello world");
PhantomReference<String>ph=new PhantomReference<>(str,queue);
System.out.println(ph.get());
这里会输出null。