最新发布 Toggle Comment Threads | 键盘快捷键

  • tanlun 10:04 am on August 13, 2011 固定链接 | 回复  

    《深入java虚拟机》-第5章java虚拟机(3) 

    我们知道一个java程序独占一个java虚拟机实例,而一个java虚拟机只存在一个堆空间,所有的类型实例和数组都放在这一个堆空间中。和方法区一样,对空间也不必是连续的内存区。

    Advertisements
     
  • tanlun 9:14 am on August 13, 2011 固定链接 | 回复
    Tags: , ,   

    《深入java虚拟机》-第5章java虚拟机(2) 

    由不同的类装载器装载的类将被放在虚拟机内部的不同命名空间中。

    用户自定义的类装载器是普通的java对象,它的类必须派生子java.lang.ClassLoader类。

    对于每一个被装载的类型,java虚拟机都会为它创建一个java.lang.Class类的实例来代表该类型。和所有其他对象一样,用户自定义的类装载器以及Class类的实例都放在内存中的堆中,而装载的类型信息则位于方法区中。

    当虚拟机装载某个类型时,它通过类装载器定位到相应的class文件,然后读入这个class文件–线性二进制数据流–然后传输到虚拟机中。虚拟机提取其中的类型信息存储在方法区中,该类型中的类(静态)变量也是存储在方法区中的。这些类型信息都包括:

    这个类型的全限定名,这个类型的直接超类的全限定名,属于类类型还是接口类型,这个类型的访问修饰符,任何直接超接口的全限定名的有序列表,这个类型的常量池,字段信息,方法信息,除了常量以外的所有类(静态)变量,一个到类ClassLoader的引用,一个到Class类的引用等,下面分别描述这些数据。

    先解释下“全限定名”的概念:在java class文件和虚拟机中,类型名都是以全限定名的形式出现。在java源代码中,全限定名由类所属包名外加“.”,再加上类名组成。例如,java类Object的包名为java.lang,所以它的全限定名为java.lang.Object。

    类(静态)变量,是所有类实例共享的,但是即使没有实例,这些变量也可以被访问,所有它们只与类有关,与实例无关,所以也是作为类型信息存放在方法区的。

    指向ClassLoader类的引用,每个类型被装载时,虚拟机都要记录它是被启动类装载器还是被用户自定义类装载器装载的,如果是用户自定义的类装载器装载的,那么虚拟机必须在类型信息中存储对该装载器的引用,这时作为方法表中的类型数据的一部分存储的。

    指向Class类的应用,对于每一个被装载的类型,不管是接口还是类,虚拟机都会相应地为它创建一个java.lang.Class类的实例。通常可以使用getClass()或者forName(String className)的方法获取该类型的Class实例的引用,获取到该引用之后,就可以通过Class的方法获取这个类型的相关信息了。

    常量池,虚拟机必须为每一个被装载的类型维护一个常量池。常量池就是该类型所用常量的有序集合,包括直接常量(string、integer和floating point常量)和对其他类型、字段和方法的符号引用。因为常量池存储了用到的所有类型、字段和方法的符号引用,所以它在java程序的动态连接中起到了核心的作用。

     
  • tanlun 7:53 am on August 13, 2011 固定链接 | 回复
    Tags: , ,   

    《深入java虚拟机》-第3章安全(1) 

    一旦java虚拟机将一个名为Volcano的类装入到一个特定的命名空间中,它就不能再装载名为Volcano的其他类到相同的命名空间了。换句话说,java虚拟机可以通过创建多个类装载器创建多个命名空间,从而加载多个Volcano类,即一个java程序可以装载具有同一个全限定名的多个类型。

    用户自定义类装载器经常依赖其他类装载器–至少依赖于虚拟机启动时创建的启动类装载器–来帮助它实现一些类装载请求。类装载器请求另一个类装载器装载类型的过程被形式化,称为“双亲委派模式”:

    除启动类装载器以外的每一个类装载器,都有一个“双亲”类装载器,在某一个类装载器试图装载某个类型之前,它会先默认请求它的“双亲”类装载器来装载这个类型,这个委派过程会一直向上,直到达到启动类装载器。如果其中一个“双亲”类装载器有能力装载该类,则这个类装载器返回这个类型。否则,它将自己试图装载该类型。换句话说,先由父辈出马,老的不行,小的才有资格自己来装载。

    启动类装载器,只负责装载那些核心java api的class文件,因为核心java api的class文件是用于启动java虚拟机的class文件,所以启动类装载器由此得名,它也是所有类装载器的“祖宗”。:)

    系统类装载器,指的是由java应用程序创建的、用户自定义类装载器的默认委派双亲,它也是由java虚拟机自己创建的。

     
  • tanlun 11:36 am on August 10, 2011 固定链接 | 回复
    Tags: , ,   

    《深入JAVA虚拟机》-第5章java虚拟机(1) 

    java虚拟机的线程分为守护线程和非守护线程。守护线程是由java虚拟机自己使用的,比如执行垃圾收集任务的线程。java程序的初始类中main方法,是该程序初始线程的起点,任何线程都是这个线程启动的。这个初始线程属于非守护线程。一旦初始线程开启后,java虚拟机实例也就创建运行了,直到所有非守护线程都终止时,虚拟机实例才自动退出。 当java虚拟机运行时,它需要内存来存储许多东西,例如,字节码,从已装载的class文件中得到的其他信息,程序创建的对象,传递给方法的参数,返回值,局部变量,以及运算的中间结果等,java虚拟机把这些东西都组织到几个“运行时数据区”中,以便管理。

    图中的绿色即方法区和堆。每个java虚拟机实例都有一个方法区和一个堆,它们是虚拟机实例内部所有线程共享的。当虚拟机装载一个class文件时,它会从这个class文件包含的二进制数据中解析类型信息,然后把这些类型信息放到方法区中。当程序运行时,虚拟机会把该程序运行时创建的对象都放在堆中。

    当每个一个线程被创建时,它都将得到它自己的出程序计数器(PC寄存器)和一个java栈。如果线程正在执行一个java方法(非本地方法),那么程序计数器的值总是指示下一条将被执行的指令。而它的java栈总是存储该线程中java方法调用的状态-包括它的局部变量、参数、返回值以及运算中间结果等。而本地方法调用的状态则是以某种依赖于具体实现的方式存储在本地方法栈中。

     
  • tanlun 11:19 am on August 10, 2011 固定链接 | 回复
    Tags: ,   

    《深入java虚拟机》-第1章java体系结构(1) 

    java虚拟机的主要任务就是装载class文件并且执行其中的字节码。

    java虚拟机是一台抽象的计算机,其规范定义了每个虚拟机都必须实现的特性,但是为每个特性实现都留下了很多选择。举个例子,虽然每个java虚拟机器都必须能够执行字节码,但是用何种技术是可以选择的。而且它的规范灵活,你可以实用纯粹软件的方式实现,也可以由硬件来完成。

    java虚拟机包含一个类加载器class loader,它可以从程序和java api中转载class文件(java api中只有程序执行时需要的那些类才会被加载)。字节码由执行引擎来执行。

    一个java应用程序可以使用两类装载器:启动(bootstrap)类装载器和用户自定义的类装载器。

    启动类装载器,又被称为系统类装载器,默认类装载器,这是系统唯一的,是java虚拟机实现的一部分。每一个类被加载时,java虚拟机会监视这个类,是被启动类装载器,还是被自定义装载器加载,这个类在使用的过程中,如果还引用了别的类,java虚拟机会使用装载该类的装载器去装载其他类。所以,默认情况下,被装载的类只能看到同一类装载器装载的别的类。被不同的类装载器装载的类存放在不同的命名空间中,它们不能相互访问,除非应用程序显式地运行这样做。

    java虚拟机和class文件在java平台无关性方面起到了关键作用。对于传统的c或者c++,使用这些语言编写的程序通常首先会被编译,然后被连接成单独的、专门支持特定硬件平台和操作系统的二进制文件。而通常情况下一个平台上的二进制可执行文件不能在其他平台上工作。当编译和连接一个c++程序的时候,所获的可执行二进制文件只能在指定的硬件平台和操作系统上运行,因为这个二进制文件包含了目标处理器的机器语言。

    java编译器将java源文件的指令翻译成字节码,包含在class文件中,这种字节码被称为java虚拟机的“机器语言”。所以,java class文件可以运行在任何支持java虚拟机的硬件平台和操作系统上。

     
  • tanlun 8:42 am on July 19, 2010 固定链接 | 回复  

    XFire Client实现遇到的问题 

    Exception in thread “main” org.codehaus.xfire.XFireRuntimeException: Could not  invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: There must be a method name element.

    解决办法还是很简单:将wsdlURL后面的”?wsdl”去掉即可:

    Service serviceModel = new ObjectServiceFactory().create(MyService.class);
    MyService service = (MyService) new XFireProxyFactory().create(serviceModel,
                “http://localhost:8080/ninthDemo/services/myService“);

     
  • tanlun 8:26 am on July 19, 2010 固定链接 | 回复  

    本地mvn jetty:run时常遇到的异常 

    2010-07-19 16:17:42.670::WARN:  failed HandlerCollection@7f8922
    java.lang.UnsupportedClassVersionError: Bad version number in .class file

    使用mvn clean情况一下编译好的文件,重新mvn jetty:run就好了。

     
  • tanlun 2:14 am on July 6, 2010 固定链接 | 回复  

    VPN vs Proxy ? 

    通常我们听到的代理大致有三类:http/s proxy, socks proxy and VPN (实际上不是代理)。

    其中http/s proxy, socks proxy属一类,作为代理服务器,它们类似一种网络访问的中介,每次我们访问一个web网站时,实际上时先去访问代理服务器,再由代理服务器访问目标网站。而且这样是匿名,也就是说被请求的网站并不知道你的原始的访问地点在哪里。网上流传的gappproxy翻墙就是一个典型的例子,在gae上建立一个代理服务器fetchserver后,然后在本机开启gappproxy的代理程序,每次访问任何网站时,其实是把请求发给代理服务器,然后由代理服务器去请求目标网站,因为gae都是在美国的服务器,同时目前访问gae还是ok的,所以整个过程都是没问题的。(我们知道GFW是通过黑名单来过滤访问指定网站的数据包,如果把gae服务器也纳入黑名单,那就杯具了。)

    如果只是网上冲浪或者通过浏览器使用的活动,那样的话http/s proxy就可以了,像GAE中的gappproxy就是其中的一个例子。如果你需要做更多的事情,而不仅仅是websurf,那样就需要使用socks proxy,它能更灵活地为你提供除了网页浏览其他的一些功能。那VPN又是什么呢?VPN,Virtual private Network,中文名是“虚拟专用网络”。一个简单的解释就是,在公共网络中建立的两点之间的专用的虚拟隧道。也可以理解为虚拟出来的企业内部专线。安全通信是通过加密来保证的,加密算法运用运用于你的实时通信中,保证在公用的网络中两点之间的数据通信不被其他人截取或访问,也就是说,在两点之间建立了一个专用的“隧道”。

    相比较来看,proxy server有很多的免费的解决方案,它也能提供匿名的web browsing。但是,安全性就差很多,你和代理服务器之间的通讯是完全透明的。(SSL proxy可以进行适当的保护),与VPN相比,代理的速率也比较低。VPN比http/s proxy和socks proxy的安全性就高很多了。VPN需要更多的硬件和软件来支持,所以它是需要付费的。当然它的速率也是最高。除此之外,VPN加密本台机器上的所有网络通信,包括你的browsing,email,voip,chat等所有网络传输。而不像http/s proxy只对你的浏览器访问web网站做代理。

    以上文字参考:

    《Proxy vs VPN… Who wins?》

    《what is a VPN service?》

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
回复
e
编辑
o
Show/Hide comments
t
返回顶部
l
Go to login
h
Show/Hide help
shift + esc
取消