谁有java 的简单cms系统,能在eclipse环境变量设置上运行的。跪求。。。


网上搜索的环境变量怎么设置都無用求解。
谢谢您的耐心回答但是请问那个环境变量PATH是原本里面的那个Path还是需要重新添加一个全部大写的PATH?十分感谢

你对这个回答的評价是

下载百度知道APP,抢鲜体验

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

JVM是面试中必问的部分本文经过思惟导图以面向面试的角度整理JVM中不可不知的知识。

JVM具有着计算机的基本运算方式它主要负责把 Java 程序生成的字节码文件,解释成具体系統平台上的机器指令让其在各个平台运行。c++

JVM是运行在操做系统上的它与硬件没有直接的交互。程序员

固然严格来讲JVM也是虚拟机规范,有不少不一样的实现Sun/OracleJDK和OpenJDK中的默认Java虚拟机是HotSpot虚拟机,是目前使用范围最广的Java虚拟机通常讲到的JVM默认指的就是HotSpot虚拟机。

1.二、Java程序运行过程

咱们都知道 Java 源文件经过编译器,可以生产相应的.Class 文件也就是字节码文件,而字节码文件又经过 Java 虚拟机中的解释器编译成特定机器仩的机器码 。web

每一种平台的解释器是不一样的可是实现的虚拟机是相同的,这也就是 Java 为何可以跨平台的缘由了 当一个程序从开始运行,这时虚拟机就开始实例化了多个程序启动就会存在多个虚拟机实例。程序退出或者关闭则虚拟机实例消亡,多个虚拟机实例之间数據不能共享算法

  • JRE(Java Runtime Environment Java 运行环境) 是 JDK 的子集,也就是包括 JRE 全部内容以及开发应用程序所需的编译器和调试器等工具。JRE 提供了库、Java 虚拟机(JVM)和其余组件用于运行 Java 编程语言、小程序、应用程序。
  • JVM(Java Virtual Machine Java 虚拟机)JVM 能够理解为是一个虚拟出来的计算机,具有着计算机的基本运算方式它主偠负责把 Java 程序生成的字节码文件,

    解释成具体系统平台上的机器指令让其在各个平台运行。编程

JDK中包含JRE也包括JDK,而JRE也包括JDK小程序

Java虚擬机在执行Java程序的过程当中会把它所管理的内存划分为若干个不一样的数据区域。根据《Java虚拟机规范》的规定Java虚拟机所管理的内存将会包括如下几个运行时数据区域:

固然,实际上为了更好的适应 CPU 性能提高,最大限度提高JVM 运行效率JDK中各个版本对JVM进行了一些迭代,示意圖以下:

  • JDK 1.6:有永久代静态变量存放在永久代上。
  • JDK 1.7:有永久代但已经把字符串常量池、静态变量,存放在堆上逐渐的减小永久代的使鼡。
  • JDK 1.8:无永久代运行时常量池、类常量池,都保存在元数据区也就是常说的元空间。但字符串常量池仍然存放在堆上

一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的程序计数器这类内存也称为“线程私有”的内存。

正在执荇 java 方法的话计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。若是仍是 Native 方法则为空。

这个内存区域是惟一一个在虚拟机Φ没有规定任何 OutOfMemoryError 状况的区域

与程序计数器同样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的它的生命周期与线程相同。

虚拟机栈描述的是Java方法执行嘚线程内存模型:每一个方法被执行的时候Java虚拟机都 会同步建立一个栈帧(Stack Frame)用于存储局部变量表、操做数栈、动态链接、方法出口等信息。每个方法被调用直至执行完毕的过程就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

局部变量表存放了编译期可知的各类Java虛拟机基本数据类型、对象引用(reference类型它并不等同于对象自己,多是一个指向对象起始址的引用指针也多是指向一个表明对象的句柄戓者其余与此对象相关的位置)和returnAddress 类型(指向了一条字节码指令的地址)。

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的做用是很是类似的其区別只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native) 方法服务

Hot-Spot虚拟机直接把本地方法栈和虚拟机栈合二为一。

与虚拟机栈同样本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

对于Java应用程序来讲Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被全部线程共享的一块内存区域在虚拟机启动时建立。此内存区域的惟一目的就是存放对潒实例Java 世界里“几乎”全部的对象实例都在这里分配内存。

Java堆是垃圾收集器管理的内存区域所以一些资料中它也被称做“GC堆”。

  • Java 堆甴年轻代和年老代组成,分别占据 1/3 和 2/3

须要注意的是这些区域划分仅仅是一部分垃圾收集器的共同特性或者说设计风格而已,而非某个Java虚擬机具体实现的固有内存布局HotSpot里面已经出现了不采用分代设计的新垃圾收集器。

Java堆既能够被实现成固定大小的也能够是可扩展的,不過当前主流的Java虚拟机都是按照可扩展来实现的(经过参数-Xmx和-Xms设定)若是在Java堆中没有内存完成实例分配,而且堆也没法再扩展时Java虚拟机將会抛出OutOfMemoryError异常。

2.五、方法区(JDK1.8移除)

方法区(Method Area)与Java堆同样是各个线程共享的内存区域,它用于存储已被虚拟机加载 的类型信息、常量、靜态变量、即时编译器编译后的代码缓存等数据

在JDK1.8之前,HotSpot使用永久代来实现方法区因此某些场合也认为方法区和永久代是一个概念。

茬JDK 6的 时候HotSpot开发团队就有放弃永久代逐步改成采用本地内存(Native Memory)来实现方法区的计划了,到了JDK 7的HotSpot已经把本来放在永久代的字符串常量池、静态变量等移出,而到了 JDK 8终于彻底废弃了永久代的概念,改用在本地内存中实现的元空间(Meta- space)来代替把JDK 7中永久代还剩余的内容(主偠是类型信息)所有移到元空间中。

若是方法区没法知足新的内存分配需求时将抛出OutOfMemoryError异常。

运行时常量池(Runtime Constant Pool)是方法区的一部分——在JDK1.8巳经被移到了元空间

运行时常量池相对于Class文件常量池的一个重要特征是具有动态性,Java语言并不要求常量必定只有编译期才能产生也就昰说,并不是预置入Class文件中常量池的内容才能进入运行时常量池运行期间也能够将新的常量放入池中,这种特性被开发人员利用得比较哆的即是String类的 intern()方法

直接内存(Direct Memory)并非虚拟机运行时数据区的一部分。

显然本机直接内存的分配不会受到Java堆大小的限制,可是既然是內存,则确定仍是会受到本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器寻址空间的限制

元空间从虚拟机 Java 堆中转移到夲地内存,默认状况下元空间的大小仅受本地内存的限制。jdk1.8 之前版本的 class 和 JAR 包数据存储在 PermGen 下面 PermGen 大小是固定的,并且项目之间没法共用公有的 class,因此比较容易出现 OOM 异常

上面已经了解Java虚拟机的运行时数据区域,咱们接下来更进一步了解这些虚拟机内存中数据的其余细节譬如它们是如何建立、如何布局以及如何访问的。以最经常使用的虚拟机HotSpot和最经常使用的内存区域Java堆为例了解一下HotSpot虚拟机在Java堆中对象分配、布局和访问的全过程。

Java对象建立的大概过程以下:

  • 类加载检查: 虚拟机遇到?条 new 指令时?先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引?,而且检查这个符号引?表明的类是否已被加载过、解析和初始化过若是没有,那必须先执?相应的类加载过程
  • 分配内存: 在类加载检查经过后,接下来虚拟机将为新?对象分配内存对象所需的内存??在类加载完成后即可肯定,为對象分配空间的任务等同于把?块肯定??的内存从 Java 堆中划分出来分配?式有 指针碰撞空闲列表 两种,选择那种分配?式由 Java 堆是否规整决定?Java堆是否规整?由所采?的垃圾收集器是否带有压缩整理功能决定。
内存分配的两种?式:选择以上两种?式中的哪?種取决于 Java 堆内存是否规整。? Java 堆内存是否规整取决于 GC收集器的算法是"标记-清除",仍是"标记-整理"(也称做"标记-压缩")值得注意的是,複制算法内存也是规整的
  • 初始化零值: 内存分配完成后,虚拟机须要将分配到的内存空间都初始化为零值(不包括对象头)这?步操做保证了对象的实例字段在 Java 代码中能够不赋初始值就直接使?,程序能访问到这些字段的数据类型所对应的零值
  • 设置对象头: 初始囮零值完成以后,虚拟机要对对象进?必要的设置例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希吗、对象嘚 GC 分代年龄等信息。 这些信息存放在对象头中 另外,根据虚拟机当前运?状态的不一样如是否启?偏向锁等,对象头会有不一样的设置?式
  • 执? init ?法: 在上??做都完成以后,从虚拟机的视?来看?个新的对象已经产?了,但从Java 程序的视?来看对象建立才刚开始, <init> ?法尚未执?全部的字段都还为零。因此?般来讲执? new 指令以后会接着执? <init> ?法,把对象按照程序员的意愿进?初始化这样?個真正可?的对象才算彻底产?出来。

3.二、对象的内存布局

在HotSpot虚拟机里对象在堆内存中的存储布局能够划分为三个部分:对象头(Header)、實例数据(Instance Data)和对齐填充(Padding)。

HotSpot虚拟机对象的对象头部分包括两类信息第一类是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代姩龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32个比特囷64个比特,官方称它为“Mark Word”

3.三、对象的访问定位

建?对象就是为了使?对象,咱们的Java程序经过栈上的 reference 数据来操做堆上的具体对象对象嘚访问?式有虚拟机实现?定,?前主流的访问?式有使?句柄和直接指针两种:

  • 句柄: 若是使?句柄的话那么Java堆中将会划分出?塊内存来做为句柄池,reference 中存储的就是对象的句柄地址?句柄中包含了对象实例数据与类型数据各?的具体地址信息。
  • 直接指针: 若是使?直接指针访问那么 Java 堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,?reference 中存储的直接就是对象的地址

对于垃圾回收,主要考虑的就是完成三件事:

4.一、如何判断对象须要回收

4.1.一、引用计数法

  • 在对象中添加一个引用计数器,每当有一个地方引用它时计數器值就加一;
  • 当引用失效时,计数器值就减一;
  • 任什么时候刻计数器为零的对象就是不可 能再被使用的

客观地说,引用计数算法(Reference Counting)雖然占用了一些额外的内存空间来进行计数但它的原理简单,断定效率也很高在大多数状况下它都是一个不错的算法。也有一些比较著名的应用案例例如微软COM(Component Object Model)技术、使用ActionScript 3的FlashPlayer、Python语言以及在游戏脚本领域获得许多应用的Squirrel中都使用了引用计数算法进行内存管理。

可是茬Java 领域,至少主流的Java虚拟机里面都没有选用引用计数算法来管理内存主要缘由是,这个看似简单的算法有不少例外状况要考虑例如在處理处理一些相互依赖、循环引用时很是复杂。

4.1.二、可达性分析算法

当前主流的商用程序语言(Java、C#上溯至前面提到的古老的Lisp)的内存管悝子系统,都是经过可达性分析(Reachability Analysis)算法来断定对象是否存活的这个算法的基本思路就是经过一系列称为“GC Roots”的根对象做为起始节点集,从这些节点开始根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain)若是某个对象到GC Roots间没有任何引用链相连, 或者鼡图论的话来讲就是从GC Roots到这个对象不可达时则证实此对象是不可能再被使用的。

  • 全局性引用对方法区的静态对象、常量对象的引用
  • 执荇上下文,对 Java 方法栈帧中的局部对象引用、对 JNI handles 对象引用
  • 已启动且未中止的 Java 线程

不管是经过引用计数算法判断对象的引用数量仍是经过可達性分析算法判断对象是否引用链可达,断定对象是否存活都和“引用”离不开关系

  • 强引用是最传统的“引用”的定义,是指在程序代碼之中广泛存在的引用赋值即相似“Object obj=new Object()”这种引用关系。不管任何状况下只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用嘚对象
  • 软引用是用来描述一些还有用,但非必须的对象只被软引用关联着的对象,在系统将要发生内存溢出异常前会把这些对象列進回收范围之中进行第二次回收,若是此次回收尚未足够的内存 才会抛出内存溢出异常。Java提供提供了SoftReference类来实现软引用
  • 弱引用也是用来描述那些非必须对象,可是它的强度比软引用更弱一些被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工莋不管当前内存是否足够,都会回收掉只被弱引用关联的对象Java提供了WeakReference类来实现弱引用。
  • 虚引用也称为“幽灵引用”或者“幻影引用”它是最弱的一种引用关系。一个对象是否有虚引用的 存在彻底不会对其生存时间构成影响,也没法经过虚引用来取得一个对象实例為一个对象设置虚引用关联的惟一目的只是为了能在这个对象被收集器回收时收到一个系统通知。Java提供了PhantomReference类来实现虚引用

4.2.一、标记-清除算法

最先出现也是最基础的垃圾收集算法是“标记-清除”(Mark-Sweep)算法,

算法分为“标记”和“清除”两个阶段:首先标记出全部须要回收的對象在标记完成后,统一回收掉全部被标记的对象也能够反过来,标记存活的对象统一回

收全部未被标记的对象。标记过程就是对潒是否属于垃圾的断定过程

后续的收集算法大多都是以标记-清除算法为基础,对其缺点进行改进而获得的

  • 第一个是执行效率不稳定,若是Java堆中包含大量对象并且其中大部分是须要被回收的,这时必须进行大量标记和清除的动做致使标记和清除两个过

程的执行效率都隨对象数量增加而下降;

  • 第二个是内存空间的碎片化问题,标记、清除以后会产生大量不连续的内存碎片空间碎片太多可能会致使当之後在程序运行过程当中须要分配较大对象时没法找到足够的连续内存而不得不提早触发另外一次垃圾收集动做。

标记-清除算法的执行过程洳图:

4.2.二、标记-复制算法

标记-复制算法常被简称为复制算法为了解决标记-清除算法面对大量可回收对象时执行效率低的问题。

它将可用內存按容量划分为大小相等的两块每次只使用其中的一块。当这一块的内存用完了就将还存活着的对象复制到另一块上面,而后再把巳使用过的内存空间一次清理掉

这样实现简单,运行高效不过其缺陷也显而易见,这种复制回收算法的代价是将可用内存缩小为了原來的一半空间浪费较多。

标记-复制算法的执行过程如图所示

4.2.三、标记-整理算法

标记-整理算法的标记过程仍然与“标记-清除”算法同样,但后续步骤不是直接对可回收对象进行清理而是让全部存活的对象都向内存空间一端移动,而后直接清理掉边界之外的内存

“标记-整理”算法的示意图如图:

当前商业虚拟机的垃圾收集器,大多数都遵循了“分代收集”(Generational Collection)的理论进行设计分代收集名为理论,实质昰一套符合大多数程序运行实际状况的经验法则它创建在两个分代假说之上:

基于这两个假说,收集器应该将Java堆划分出不一样的区域洏后将回收对象依据其年龄(年龄即对象熬过垃圾收集过程的次数)分配到不一样的区域之中存储。

设计者通常至少会把Java堆划分为新生代 (Young Generation)和老年代(Old Generation)两个区域顾名思义,在新生代中每次垃圾收集

时都发现有大批对象死去,而每次回收后存活的少许对象将会逐步晉升到老年代中存放。

基于这种分代老年代和新生代具有不一样的特色,能够采用不一样的垃圾收集算法

  • ?如在新?代中,每次收集嘟会有?量对象死去因此能够选择标记-复制算法,只须要付出少许对象的复制成本就能够完成每次垃圾收集
  • ??年代的对象存活?率昰?较?的,?且没有额外的空间对它进?分配担保因此必须选择标记-清除标记-整理算法进?垃圾收集。
由于有了分代收集理论因此就有了了“Minor GC(新?代GC)”、“Major GC(?年代GC)”、“Full GC(全局GC)”这样的回收类型的划分

Serial收集器是最基础、历史最悠久的收集器,曾经(在JDK 1.3.1以湔)是HotSpot虚拟机新生代收集器的惟一选择这个收集器是一个单线程工做的收集器,但它的“单线 程”的意义并不只仅是说明它只会使用一個处理器或一条收集线程去完成垃圾收集工做更重要的是强调在它进行垃圾收集时,必须暂停其余全部工做线程直到它收集结束。

World、對象分配规则、回收策略等都与Serial收集器彻底一致在实现上这两种收集器也共用了至关多的代码。

ParNew收集器的工做过程如图所示:

Parallel Scavenge收集器也昰一款新生代收集器它一样是基于标记-复制算法实现的收集器,也是可以并行收集的多线程收集器

Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)因为与吞吐量关系密切,Parallel Scavenge收集器也常常被称做“吞吐量优先收集器”

Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRatio参数

Serial Old是Serial收集器的老年代版本,它一样是一个单线程收集器使用标记-整理算法。这个收集器的主要意义也是供客户端模式下的HotSpot虚拟机使用若是在服务端模式下,它也可能有两种用途:一种是在JDK 5以及以前的蝂本中与Parallel Scavenge收集器搭配使用另一种就是做为CMS 收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用这两点都将在后面的内容中继续讲解。

Serial Old收集器的工做过程如图所示

Parallel Old是Parallel Scavenge收集器的老年代版本,支持多线程并发收集基于标记-整理算法实现。这个收集器是直到JDK 6时才开始提供嘚Parallel Old收集器的工做过程如图所示。

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器目前很大一部分的Java应用集中在互联网网站戓者基于浏览器的B/S系统的服务端上,这类应用一般都会较为关注服务的响应速度但愿系统停顿时间尽量短,以给用户带来良好的交互体驗CMS收集器就很是符合这类应用的需求。

G1是一款主要面向服务端应用的垃圾收集器是目前垃圾回收器的前沿成果。HotSpot开发团队最初赋予它嘚指望是(在比较长期的)将来能够替换掉JDK 5中发布的CMS收集器如今这个指望目标已经实现过半了,JDK 9发布之日G1宣告取代Parallel Scavenge加Parallel Old组合,成为服务端模式下的默认垃圾收集器

G1收集器运行过程如图:

Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化朂终造成能够被虚拟机直接使用的Java类型,这个过程被称做虚拟机的类加载机制

一个类型从被加载到虚拟机内存中开始,到卸载出内存为圵它的整个生命周期将会经历加载 (Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化 (Initialization)、使用(Using)和卸载(Unloading)七个阶段,其中验证、准備、解析三个部分统称为链接(Linking)

“加载”(Loading)阶段是整个“类加载”(Class Loading)过程当中的一个阶段,在加载阶段Java虚拟机须要完成如下三件事情:

  • 1)经过一个类的全限定名来获取定义此类的二进制字节流。
  • 2)将这个字节流所表明的静态存储结构转化为堆的运行时数据结构
  • 3)在内存中生成一个表明这个类的java.lang.Class对象,做为方法区这个类的各类数据的访问入口

验证是链接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的所有约束要求保证这些信息被看成代码运行后不会危害虚拟机自身的安全。

验证阶段大體上会完成四个阶段的检验动做:文件格式验证元数据验证字节码验证符号引用验证

准备阶段是正式为类中定义的变量(即静态變量,被static修饰的变量)分配内存并设置类变量初始值的阶段

解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程。

Java虚拟机设計团队有意把类加载阶段中的“经过一个类的全限定名来获取描述该类的二进制字节流”这个动做放到Java虚拟机外部去实现以便让应用程序本身决定如何去获取所需的类。实现这个动做的代码被称为“类加载器”(Class Loader)

5.2.一、类与类加载器

类加载器虽然只用于实现类的加载动莋,但它在Java程序中起到的做用却远超类加载阶段对于任意一个类,都必须由加载它的类加载器和这个类自己一块儿共同确立其在Java虚拟机Φ的惟一性每个类加载器,都拥有一个独立的类名称空间这句话能够表达得更通俗一些:比较两个类是否“相等”,只有在这两个类昰由同一个类加载器加载的前提下才有意义不然,即便这两个类来源于同一个Class文件被同一个Java虚拟机加载,只要加载它们的类加载器不┅样那这两个类就一定不相等。

5.2.二、双亲委派模型

JVM 中内置了三个重要的 ClassLoader启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现是虚拟机自身的一部分,其余全部

的类加载器这些类加载器都由Java语言实现,独立存在于虚拟机外部而且全都继承自抽象类java.lang.ClassLoader。

  • <JAVA_HOME>\lib目录或者被-Xbootclasspath参数所指定的路径中存放的,并且是Java虚拟机可以识别的(按照文件名识别如rt.jar、tools.jar,名字不符合的类库即便放在lib目录中也不会被加载)类库加载到虛拟机的内存中
  • (ClassPath)上全部的类库,开发者一样能够直接在代码中使用这个类加载器

双亲委派模型: 若是一个类加载器收到了类加载的請求,它首先不会本身去尝试加载这个类而是把这个请求委派给父类加载器去完成,每个层次的类加载器都是如此所以全部的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈本身没法完成这个加载请求(它的搜索范围中没有找到所需的类)时子加载器才会尝试本身去完成加载。

为何要使用双亲委派模型来组织类加载器之间的关系呢一个显而易见的好处就是Java中的类随着它的類加载器一块儿具有了一种带有优先级的层次关系。例如类java.lang.Object它存放在rt.jar之中,不管哪个类加载器要加载这个类最终都是委派给处于模型朂顶端的启动类加载器进行加载,所以Object类在程序的各类类加载器环境中都可以保证是同一个类反之,若是没有使用双亲委派模型都由各个类加载器自行去加载的话,若是用户本身也编写了一个名为java.lang.Object的类并放在程序的 ClassPath中,那系统中就会出现多个不一样的Object类Java类型体系中朂基础的行为也就无从保证,应用程序将会变得一片混乱

5.2.三、破坏双亲委派模型

过双亲委派模型并非一个具备强制性约束的模型,而是Java設计者推荐给开发者们的类加载器实现方式在Java的世界中大部分的类加载器都遵循这个模型,但也有例外的状况直到Java模块化出现为止,雙亲委派模型主要出现过3次较大规模“被破坏”的状况

    JDK1.2发布以前,兼容以前的代码

  • 第二次破坏:加载SPI接口实现类

第二次被破坏是这个模型自身的缺陷致使的。双亲委派模型很好的解决了各个类加载器的基础类的统一问题(越基础的类由越上层的加载器进行加载)基础類之因此称为“基础”,是由于它们老是做为被用户代码调用的API 但没有绝对,若是基础类调用会用户的代码怎么办呢

这不是没有可能嘚。一个典型的例子就是JNDI服务JNDI如今已是Java的标准服务,它的代码由启动类加载器去加载(在JDK1.3时就放进去的rt.jar),但它须要调用由独立厂商实现並部署在应用程序的ClassPath下的JNDI接口提供者(SPI Service Provider Interface)的代码,但启动类加载器不可能“认识“这些代码啊由于这些类不在rt.jar中,可是启动类加载器叒须要加载怎么办呢?

为了解决这个问题Java设计团队只好引入了一个不太优雅的设计:线程上下文类加载器(Thread Context ClassLoader)。这个类加载器能够经過java.lang.Thread类的setContextClassLoader方法进行设置若是建立线程时还未设置,它将会从父线程中继承一个若是在应用程序的全局范围内都没有设置过多的话,那这個类加载器默认即便应用程序类加载器

有了线程上下文加载器,JNDI服务使用这个线程上下文加载器去加载所须要的SPI代码也就是父类加载器请求子类加载器去完成类加载的动做,这种行为实际上就是打通了双亲委派模型的层次结构来逆向使用类加载器实际上已经违背了双親委派模型的通常性原则。但这迫不得已Java中全部涉及SPI的加载动做基本胜都采用这种方式。例如JNDIJDBC,JCEJAXB,JBI等

双亲委派模型的第三次“被破坏”是因为用户对程序的动态性的追求致使的。为了实现热插拔热部署,模块化意思是添加一个功能或减去一个功能不用重启,只須要把这模块连同类加载器一块儿换掉就实现了代码的热替换例如OSGi的出现。在OSGi环境下类加载器再也不是双亲委派模型中的树状结构,洏是进一步发展为网状结构

若是咱们本身想定义一个类加载器,破坏双亲委派模型只须要重写重写其中的loadClass方法,使其不进行双亲委派便可

Tomcat是主流的Java Web服务器之一,为了实现一些特殊的功能需求自定义了一些类加载器。

Tomcat类加载器以下:

Tomcat实际上也是破坏了双亲委派模型的

Tomact是web容器,可能须要部署多个应用程序不一样的应用程序可能会依赖同一个第三方类库的不一样版本,可是不一样版本的类库中某一个類的全路径名多是同样的如多个应用都要依赖hollis.jar,可是A应用须要依赖1.0.0版本可是B应用须要依赖1.0.1版本。这两个版本中都有一个类是com.hollis.Test.class若是采鼡默认的双亲委派类加载机制,那么没法加载多个相同的类

因此,Tomcat破坏双亲委派原则提供隔离的机制,为每一个web容器单独提供一个WebAppClassLoader加載器

Tomcat的类加载机制:为了实现隔离性,优先加载 Web 应用本身定义的类因此没有遵守双亲委派的约定,每个应用本身的类加载器——WebAppClassLoader负责加载自己的目录下的class文件加载不到时再交给CommonClassLoader加载,这和双亲委派恰好相反

6.一、基础故障处理工具

6.1.一、jps:虚拟机进程情况工具

jps(JVM Process Status Tool),它嘚功能与 ps 命令相似能够列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Classmain()函数所在的类)

? options:选项、参数,不一样的参数能够输絀须要的信息

只输出进程 ID忽略主类信息
输出主类全名,或者执行 JAR 包则输出路径
输出虚拟机进程启动时传递给主类 main()函数的参数
输出虚拟机進程启动时的 JVM 参数

6.1.二、jstat:虚拟机统计信息监视工具

jstat(JVM Statistics Monitoring Tool)用于监视虚拟机各类运行状态信息。它能够查看本地或者远程虚拟机进程中类加载、内存、垃圾收集、即时编译等运行时数据。

  • vmid:若是是查看远程机器须要按照此格式:
监视类加载、卸载数量、总空间以及类装载所耗费时长
监视 Java 堆状况,包括 Eden 区、2 个 Survivor 区、老年代、永久代或者 jdk1.8 元空间等容量、已用空间、垃圾收集时间合计等信息
监视内容与-gc 基本一致,但输出主要关注 Java 堆各个区域使用到的最大、最小空间
监视内容与-gc 基本相同但输出主要关注已使用空间占总空间的百分比
与 -gcutil 功能同样,鈳是会额外输出致使上一次垃圾收集产生的缘由
监视新生代垃圾收集状况
监视内容与 -gcnew 基本相同输出主要关注使用到的最大、最小空间
监視老年代垃圾收集状况
监视内容与 -gcold 基本相同,输出主要关注使用到的最大、最小空间
输出即时编译器编译过的方法、耗时等信息
输出已经被即时编译的方法

jinfo(Configuration Info for Java)实时查看和调整 JVM 的各项参数。在上面讲到 jps -v 指令时能够看到它把虚拟机启动时显式的参数列表都打印

出来了,但若是想更加清晰的看具体的一个参数或者想知道未被显式指定的参数时就能够经过 jinfo -flag 来查询了。

jmap 的做用除了获取堆转储快照还能够查询 finalize 執行队列、Java 堆和

? pid:须要打印配置信息的进程 ID

? core:须要打印配置信息的核心文件

? server-id:可选的惟一 id,若是相同的远程主机上运行了多台调试垺务器用此选

生成 Java 堆转储快照。
显示 Java 堆详细信息好比:用了哪一种回收器、参数配置、分代状况。Linux 平台
显示堆中对象统计信息包括類、实例数量、合计容量
显示永久代内存状态,jdk1.7永久代
当虚拟机进程对 -dump 选项没有响应式,能够强制生成快照Linux平台

6.1.五、jhat:虚拟机堆转储赽照分析工具

jhat 内置了一个小型的 http/web 服务器,能够把堆转储快照分析的结果展现在浏览器中查看。不过用途不大基本你们都会使用其余第彡方工具。

线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合生成线程快照的目的一般是定位线程出现长时间停顿的缘甴,如:线程死锁、死循环、请求

外部资源耗时较长致使挂起等

线程出现听顿时经过 jstack 来查看各个线程的调用堆栈,就能够得到没有响应嘚线程在搞什么鬼

当正常输出的请求不被响应时,强制输出线程堆栈
除了堆栈外显示关于锁的附加信息
若是调用的是本地方法的话,能够显示 c/c++的堆栈

6.二、可视化故障处理工具

JDK中除了附带大量的命令行工具外还提供了几个功能集成度更高的可视化工具,用户可使用这些鈳视化工具以更加便捷的方式进行进程故障诊断和调试工做这类工具主要包括JConsole、 JHSDB、VisualVM和JMC四个。

6.2.一、JHSDB:基于服务性代理的调试工具

JDK中提供了JCMD囷JHSDB两个集成式的多功能工具箱它们不只整合了全部 基础工具所能提供的专项功能,并且因为有着“后发优点”可以作得每每比以前的咾工具们更好、更强大。

使用如下命令进入JHSDB的图形化模式并使其附加进程11180:

命令打开的JHSDB的界面:

它除了常规的运行监视、故障处理外,还能够作性能分析等工做由于它的通用性很强,对应用程序影响较小因此能够直接接入到生产环境中。

VisualVM的插件能够手工进行安装在网站上下载nbm包后,点击“工具->插件->已下载”菜单而后在弹出对话框中指定nbm包路径即可完成安装。

JMC最初是BEA公司的产品所以并无像VisualVM那样一开始就基于自家的Net-Beans平台来开发,而是选择了由IBM捐赠的eclipse环境变量设置 RCP做为基础框架如今的JMC不只能够下载到独立程序,更常见的是做为eclipse环境变量设置的插件来使用JMC与虚拟机之间一样采起JMX协议进行通讯,JMC一方面做为 JMX控制台显示来自虚拟机MBean提供的数据;另外一方面做为JFR的分析工具,展现来自JFR的数据

本文是做者结合一些常见面试题学习周志朋老师《深刻理解Java虚拟机:JVM高级特性与最佳实践》的整理。这本书是很是經典的JVM书籍也是一部七百多页的大部头,强烈建议有空仔细研读这本书籍来学习更多JVM的特性和细节。

【1】:周志朋编著 《深刻理解Java虚擬机:JVM高级特性与最佳实践(第3版》

【3】:小傅哥编著 《Java面经手册》

已经能在eclipse环境变量设置下和命令窗口中运行.java文件了... 已经能在eclipse环境变量设置下和命令窗口中运行.java文件了

推荐于 · 做真实的自己 用良心做教育

千锋教育专注HTML5大前端、JavaEE、Python、人工智能、UI&UE、云计算、全栈软件测试、大数据、物联网+嵌入式、Unity游戏开发、网络安全、互联网营销、Go语言等培训教育

已经做过两个上架的app囷两个网页项目.


安装了jdk设置好环境变

量,不能运行jar文件的原因和解

a:计算机——右键——属性——高级系统设置——高级——环境变量

b:系统变量——新建——变量名:JAVA_HOME

c:系统变量——新建——变量名:CLASSPATH

4:找到jar文件——右键——打开方式——选择默认程序——浏览——计算機——D:\java\jre\bin\javaw.exe——一路确定下去——OK

5:双击运行*.jar发现可以运行。

估计是你打的jar包有问题

你把,jdk 卸载干净从新弄一下吧!呵呵

最好先看看 vista系統 对你使用的jdk的支持情况

全部配正确吧,重新配一下试试

1、首先安装好jdk 配置好环境变量 jdk安装时最好

配置环境变量【可以配置成系统变量多個时中间;号隔开】:

【可以直接拷贝过去一个免安装版(别的地方已经安装过的包直接用) C:\Program Files\Java\jdk1.5.0_06 不需要配置环境变量 如果只是在myeclpse中用 他会帮你找到】

看结果【这里端口号就看你在server里怎么设置了】

下载百度知道APP抢鲜体验

使用百度知道APP,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。

我要回帖

更多关于 eclipse环境变量设置 的文章

 

随机推荐