Java的GC垃圾回收原理与机制

ava的GC垃圾回收原理与机制

JAVA中的对象是在堆上分配,而在堆上分配存储空间的方式是昂贵的.正是由于GC才使java在堆上的空间分配速度得以于其他语言在堆栈上分配速度相媲美.java对象也不再有作用域的概念.作用域是对于引用而言的.垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收.程序可以用System.gc() 或Runtime.getRuntime().gc() 请求垃圾回收,但并不保证立即执行垃圾回收.

GC的工作原理: 引用计数,标记复制

“引用计数”是一种简单但速度很慢的垃圾回收技术.所有对象都有一个引用计数器,当有引用连接时计数器加1,当引用离开作用域时或者被置于NULL时,计数器-1,垃圾回收器会在所以包含对象引用的列表上进行遍历,当发现某个对象的引用计数为0时,就释放占用的空间.

“标记复制”的运行机制,垃圾回收器遍历包含所有引用的列表,当发现存活的对象引用时做上标记,这样当遍历完所有对象引用并做上标记的时候,执行垃圾回收,将没有标记的对象堆空间释放.

垃圾回收机制的优点:

Java的垃圾回收机制是的程序员不用担心内存空间的分配,减少了内存溢出.但同时也牺牲了一定的性能.

Hiberante_lazy延迟加载总结

如果想对实体对象使用延迟加载,必须要在实体的映射配置文件中进行相应的配置,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<hibernate-mapping>   

<class name=”net.ftng.entity.user” table=”user” lazy=”true”>

……

</class>

</hibernate-mapping>
```
通过将class的lazy属性设置为true,来开启实体的延迟加载特性。如果我们运行下面的代码:
```
User user=(User)session.load(User.class,”1”);(1)

System.out.println(user.getName());(2)

当运行到(1)处时,Hibernate并没有发起对数据的查询,
当代码运行到(2)处时,此时调用user.getName()方法,这时通过CGLIB赋予的回调机制,
target属性是否为null,如果不为空,则调用目标对象的getName方法,如果为空,则会发起数据库查询

通过一个中间代理对象,Hibernate实现了实体的延迟加载,
只有当用户真正发起获得实体对象属性的动作时,
才真正会发起数据库查询操作。
所以实体的延迟加载是用通过中间代理类完成的,
所以只有session.load()方法才会利用实体延迟加载,
因为只有session.load()方法才会返回实体类的代理类对象。

iBatis与Hibernate区别

相同点:屏蔽jdbc api的底层访问细节,使用我们不用与jdbc api打交道,就可以访问数据。
jdbc api编程流程固定,还将sql语句与java代码混杂在了一起,经常需要拼凑sql语句,细节很繁琐。
ibatis的好处:屏蔽jdbc api的底层访问细节;将sql语句与java代码进行分离;提供了将结果集自动封装称为实体对象和对象的集合的功能,queryForList返回对象集合,用queryForObject返回单个对象;提供了自动将实体对象的属性传递给sql语句的参数。

Hibernate是一个全自动的orm映射工具,它可以自动生成sql语句,ibatis需要我们自己在xml配置文件中写sql语句,hibernate要比ibatis功能负责和强大很多。因为hibernate自动生成sql语句,我们无法控制该语句,我们就无法去写特定的高效率的sql。对于一些不太复杂的sql查询,hibernate可以很好帮我们完成,但是,对于特别复杂的查询,hibernate就很难适应了,这时候用ibatis就是不错的选择,因为ibatis还是由我们自己写sql语句。

总结叉子可以理解:

hibernate 是一个ORM框架,就是java对象和数据库表中记录相映射是它是主要的一个特点
比如,一个java类,和一个数据库的表相对应,java类的成员变量和表的字段对应
而 ibatis 是一个sql map框架,就是sql语句和java对象相映射的特点 比如,sql语句,
select * from XX,这个返回的字段数据和java对象的成员变量相映射。

java日期类型在Hibernate中的处理

java日期类型在Hibernate中的处理
java中的表示日期时间的类型很多,主要有下面一些:
java.util.Calendar(和区域有关,可表示年,月,日,时,分,秒)
java.util.Date(可表示年,月,日,时,分,秒)
java.sql.Date(可表示年,月,日)
java.sql.Time (可表示时,分,秒)
java.sql.Timestamp(可表示年,月,日,时,分,秒,纳秒)
在对象定义时,究竟定义为哪种类型,我们得要求项目需求来选择不同精度的类型。

Hibernate对上面的时间类型都有很好的支持,但是,不同的类型,数据库中的字段也得选择相应的类型,以mysql为例,就存在date,time,datetime,timestamp等几种。
hibernate的映射书写时要注意,日期类型一般都要明确予以指定。如果你使用的是注解映射配置,类型选择的又是java.util.Calendar,java.util.Date,此时需要使用@Temporal 明确指定具体类型,对应的取值有TemporalType.DATE,TemporalType.TIME,TemporalType.TIMESTAMP几种。
最后,hibernate中以时间作为查询条件时,也需要明确指定传入参数类型,大家要选择带有3个参数的那个setParameter方法。

spring3mvc与struts2比较

项目刚刚换了web层框架,放弃了struts2改用spring3mvc。当初换框架的时候目的比较单纯:springmvc支持rest,我对对restful url由衷的喜欢
不用不知道 一用就发现开发效率确实比struts2高。
我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置。spring3 mvc可以认为已经100%零配置了(除了配置springmvc-servlet.xml外)
比较了一下strus2与spring3 mvc的差别:
spring3 mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去,在spring3mvc中,一个方法对应一个request上下文。
而struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入;struts2实际上是通过setter getter方法与request打交道的;struts2中,一个Action对象对应一个request上下文。

好了 我们来整理一下

spring mvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上 spring3 mvc就容易实现restful url。
struts2是类级别的拦截, 一个类对应一个request上下文;实现restful url要费劲,因为struts2 action的一个方法可以对应一个url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。
spring3 mvc的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架方法之间不共享变量
而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码 读程序时带来麻烦。
spring3 mvc的验证也是一个亮点,支持JSR303,处理ajax的请求更是方便 只需一个注解@ResponseBody ,然后直接返回响应文本即可。