tomcat中设置多项目共享jar;类包
随着服务器上的tomcat部署的项目越来越多,最近在部署一个新的项目的时候出现内存溢出的错误
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.StackTraceElement.equals(StackTraceElement.java:204)
at java.lang.Throwable.printEnclosedStackTrace(Throwable.java:688)
at java.lang.Throwable.printStackTrace(Throwable.java:666)
at java.lang.Throwable.printStackTrace(Throwable.java:720)
at java.util.logging.SimpleFormatter.format(SimpleFormatter.java:157)
at java.util.logging.StreamHandler.publish(StreamHandler.java:196)
at java.util.logging.ConsoleHandler.publish(ConsoleHandler.java:105)
at java.util.logging.Logger.log(Logger.java:522)
at java.util.logging.Logger.doLog(Logger.java:543)
at java.util.logging.Logger.logp(Logger.java:743)
at org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:198)
at org.apache.juli.logging.DirectJDKLog.error(DirectJDKLog.java:151)
at org.apache.catalina.startup.Catalina.start(Catalina.java:648)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)
Exception in thread "Timer-1" java.lang.OutOfMemoryError: PermGen space
at sun.misc.Unsafe.defineClass(Native Method)
at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:63)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:399)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:396)
at java.security.AccessController.doPrivileged(Native Method)
at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:395)
at sun.reflect.MethodAccessorGenerator.generateConstructor(MethodAccessorGenerator.java:94)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:48)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at java.lang.Class.newInstance0(Class.java:372)
at java.lang.Class.newInstance(Class.java:325)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:250)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1042)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:531)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:221)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503)
at java.sql.DriverManager.getConnection(DriverManager.java:579)
at java.sql.DriverManager.getConnection(DriverManager.java:221)
at cn.com.pujiConvert.util.DbUtil.connect(DbUtil.java:37)
at cn.com.pujiConvert.util.DbUtil.<init>(DbUtil.java:25)
at cn.com.pujiConvert.dao.Document.getDocumentInfo(Document.java:33)
at cn.com.pujiConvert.convert.ConvertDocumentToPdf.getDocInfo(ConvertDocumentToPdf.java:49)
at cn.com.pujiConvert.convert.ConvertDocumentToPdf.getConvertPdfResult(ConvertDocumentToPdf.java:204)
at cn.com.pujiConvert.timer.ConvertTimerTask.convertDocumentToPdfTask(ConvertTimerTask.java:16)
at cn.com.pujiConvert.timer.ConvertTimerTask.run(ConvertTimerTask.java:49)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
以上提示说永久存续区的内存溢出。永久存续区的内存主要存储和加载Class和Meta信息,垃圾回收器不会回收这一区域的内存,只会回收堆内存。如何解决上面的永久存续期内存溢出问题呢?主要有两种方式
增大jvm的非堆内存
我们可以通过-xms和-xmax设定初始的和最大的永久存续区的内存大小。默认的永久存续期的初始内存为物理内存的1/64,最大的内存为1/4。若服务器操作系统为32位时,不能永久存续区的最大内存不能超过2G,64位操作系统不受此限制。
通过tomcat设定shared lib目录方式
虽然通过修改启动tomcat的jvm内存参数,增大vm的堆内存来解决可以解决这个问题,但是这个无法根本解决这个问题。
我们通过tomcat设定shared lib实现所有项目共享相同的jar类包,通过这种方式有两个好处
1、避免各个项目重复加载相同的jar类包,占用了大量的永续区的内存
2、提高了tomcat的启动速度。因为减少了各个项目中的重复jar类包reload,tomcat的reload速度得到提升。
配置shared lib
打开进入tomcat/conf/目录。打开catalina.properties配置文件,修改两个地方
1、找到shared.loader=位置,设置共享目录地址
shared.loader=${catalina.base}/shared/lib,${catalina.base}/shared/lib/*.jar
2、找到common.loader位置,并追加shared lib目录地址
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,${catalina.base}/shared/lib,${catalina.base}/shared/lib/*.jar
3、自行创建${catalina.base}/shared/lib,${catalina.base}/shared/lib/路径,并将共享的jar类包放在该目录下
特别说明:jar共享目录可以在tomcat目录下,也可以自行定义一个绝对路径。如果是相对路径只能相对于${catalina.base}/。实现jar共享方式在以上shared.loader和common.loader中任选一种即可,不过个人倾向于使用shared.dir方式。
补充:toncat类加载机制
- Commonclassloader:负责装载$CATALINA_HOME/common目录下的所有类和jar包,详细的配置可参考$CATALINA_HOME/conf/catalina.properties文件中的common.loader配置;该classloader装载的类对于Server class loader和Webapp class loader是可见的;Commonclass
loader在Tomcat启动时创建,其parent classloader是System class loader; - Server classloader:负责装载Tomcat的核心类,位于$CATALINE_HOME/server目录下的所有类和jar,可由catalina.propreties中的server.loader配置指定;它在Tomcat启动时被创建,其parent loader是Commonclass loader;
- Sharedclass loader:负责装载webapp公用的类,可以用户通过catalina.properties文件中的shared.loader属性来指定;它在Tomcat启动时被创建,其parentloader也是Common class loader;
- Webappclassloader:这个比较特殊,它只负责加载各自app中WEB-INF/classes以及WEB-INF/lib下的类;其parentloader虽然是Shared class loader,但其加载策略和默认的类加载机制不太一样;
No Spring WebApplicationInitializer types detected on classpath
这个是因为spring 3.1以后在加载前会自动先扫描,查找WebApplicationInitializer的实现类
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
如果自行定义加载,不需要自动扫描,可以通过metadata-complete="true"关闭自动扫描
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
metadata-complete="true">
参考资料
1、http://blog.sina.com.cn/s/blog_4db5ab6701013kuw.html
2、http://blog.csdn.net/java_wliang/article/details/18044507
tomcat中设置多项目共享jar;类包的更多相关文章
- Tomcat打包时多项目共享jar和精确指定jar版本
在产品打包发布时一个tomcat中如果存在多个war,部署的一般方式是部署到%TOMCAT_HOME%/webapps目录下,目录结构遵循J2EE规范,把引用的jar放到%TOMCAT_HOME%/w ...
- 在Tomcat中部署Web项目的操作方法,maven项目在Tomcat里登录首页报404
maven项目在Tomcat里登录首页报404, 解决:编辑conf/server.xml进行配置<Host>里的<Context>标签里的path. <Context ...
- 在Tomcat中部署web项目的三种方式
搬瓦工搭建SS教程 SSR免费节点:http://www.xiaokeli.me 在这里介绍在Tomcat中部署web项目的三种方式: 1.部署解包的webapp目录 2.打包的war文件 3.Man ...
- linux 环境下tomcat中部署jfinal项目
tomcat中部署jfinal项目 问题现象如下图 问题描述: 我在自己的windows7系统上tomcat下面跑这个项目没有任何问题吗,但是当我把项目上传到linux服务器上的tomcatwebap ...
- eclipse引入jar类包的源代码
为了方便查看源代码,有时候需要对jar类包,引入源代码. 下载源代码 源代码是zip或者rar的压缩包 引入到项目中
- 使用eclipse在tomcat中设置项目启动的虚拟路径
很多时候我们在启动项目的时候都会在浏览器输入"localhost:+端口号+项目名称" 其实tomcat是可以省去这种麻烦的,通过设置项目的虚拟路径就可访问项目了 第一步 选择ec ...
- tomcat 中无法添加项目等问题的解决方案
博客地址:http://www.moonxy.com 一.前言 今天新建了一个 maven 项目,添加程序文件之后,发现无法添加项目,然后修改配置,将应用添加到了 tomcat,启动时又报错,解决出现 ...
- Tomcat中部署WEB项目的四种方法
对Tomcat部署web应用的方式总结,常见的有以下四种: 1.[使用控制台部署] 访问Http://localhost:8080,并通过Tomcat Manager登录,进入部署界面即可. 2.[利 ...
- SharpDX初学者教程第1部分:在Visual Studio 2013中设置SharpDX项目
原文 http://www.johanfalk.eu/blog/sharpdx-tutorial-part-1-setting-up-a-sharpdx-project-in-visual-studi ...
随机推荐
- css揭秘之linear-gradient
很神奇的背景设置, 看代码, <html> <title>css</title> <style> .content { background: line ...
- PHP 'ext/gd/gd.c'信息泄漏漏洞
漏洞版本: PHP 5.5.x 漏洞描述: CVE ID:CVE-2014-2020 PHP是一种HTML内嵌式的语言. PHP 'ext/gd/gd.c'没有检查数据类型,允许远程攻击者使用字符串或 ...
- 谈谈分布式事务之三: System.Transactions事务详解[下篇]
在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTra ...
- UVA 11426 GCD - Extreme (II) 欧拉函数
分析:枚举每个数的贡献,欧拉函数筛法 #include <cstdio> #include <iostream> #include <ctime> #include ...
- UVA 540 Team Queue
思路:使用优先队列,按队伍出现的时刻和自身出现的时刻定义优先级,同时记录此时刻队列里是否有自己队伍的人,一开始没注意,wa了两发. #include<map> #include<qu ...
- [Stephen]C#中调用C++动态链接库
1.主程序声明引用外部方法,并完成方法调用
- 使用 Windows PowerShell 管理Windows Azure映像
你可以使用 Azure PowerShell 模块中的 cmdlet 管理可供你的 Azure 订阅使用的映像.这包括 Azure 提供的映像以及你上载的映像.对于某些映像任务,你还可以使用 Azur ...
- Codeforces295A - Greg and Array(线段树的成段更新)
题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...
- Solution for When browse http://xxx/ReportServer Show Error (rsAccessDenied)
Issue: Reporting Services Error The permissions granted to user 'IDEAAM\William' are insufficient fo ...
- A Tour of Go For is Go's "while"
At that point you can drop the semicolons(分号): C's while is spelled for in Go. package main import & ...