我最近做了this tutorial并且代码运行正常。然后,今天,我在eclipse中重新打开了项目并选择了Run As ... Run on Server。应用程序似乎从eclipse控制台中运行的日志中经历了正常的加载过程,但是当我希望应用程序在浏览器中加载时,在eclipse控制台中出现以下错误消息:
Exception in thread "http-bio-8080-exec-3" java.lang.OutOfMemoryError: PermGen space
我之前也运行了来自this tutorial的代码,并打开了一些blob文件,但我不认为这会导致问题,因为即使我关闭所有内容并重新启动计算机,此错误仍然存在在执行运行之前...再次在服务器上运行以下代码。
我用Google搜索错误和read postings关于内存泄漏的事情,例如将大量文件完全加载到内存中而不是使用输入流等。但是当我分析应用程序中的所有代码时,我找不到任何大变量。我发布下面的代码。如果我还有其他任何内容可以帮助您找到问题,请告诉我。
有人能告诉我内存泄漏的位置吗?
这是Link Controller:
@Controller
public class LinkController {
@RequestMapping(value="/")
public ModelAndView mainPage() {return new ModelAndView("home");}
@RequestMapping(value="/index")
public ModelAndView indexPage() {return new ModelAndView("home");}
}
这是团队控制员:
@Controller
@RequestMapping(value="/team")
public class TeamController {
@Autowired
private TeamService teamService;
@RequestMapping(value="/add", method=RequestMethod.GET)
public ModelAndView addTeamPage() {
ModelAndView modelAndView = new ModelAndView("add-team-form");
modelAndView.addObject("team", new Team());
return modelAndView;
}
@RequestMapping(value="/add", method=RequestMethod.POST)
public ModelAndView addingTeam(@ModelAttribute Team team) {
ModelAndView modelAndView = new ModelAndView("home");
teamService.addTeam(team);
String message = "Team was successfully added.";
modelAndView.addObject("message", message);
return modelAndView;
}
@RequestMapping(value="/list")
public ModelAndView listOfTeams() {
ModelAndView modelAndView = new ModelAndView("list-of-teams");
List<Team> teams = teamService.getTeams();
modelAndView.addObject("teams", teams);
return modelAndView;
}
@RequestMapping(value="/edit/{id}", method=RequestMethod.GET)
public ModelAndView editTeamPage(@PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("edit-team-form");
Team team = teamService.getTeam(id);
modelAndView.addObject("team",team);
return modelAndView;
}
@RequestMapping(value="/edit/{id}", method=RequestMethod.POST)
public ModelAndView edditingTeam(@ModelAttribute Team team, @PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("home");
teamService.updateTeam(team);
String message = "Team was successfully edited.";
modelAndView.addObject("message", message);
return modelAndView;
}
@RequestMapping(value="/delete/{id}", method=RequestMethod.GET)
public ModelAndView deleteTeam(@PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("home");
teamService.deleteTeam(id);
String message = "Team was successfully deleted.";
modelAndView.addObject("message", message);
return modelAndView;
}
}
这是TeamDAOImpl:
@Repository
public class TeamDAOImpl implements TeamDAO {
@Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession() {return sessionFactory.getCurrentSession();}
public void addTeam(Team team) {getCurrentSession().save(team);}
public void updateTeam(Team team) {
Team teamToUpdate = getTeam(team.getId());
teamToUpdate.setName(team.getName());
teamToUpdate.setRating(team.getRating());
getCurrentSession().update(teamToUpdate);
}
public Team getTeam(int id) {
Team team = (Team) getCurrentSession().get(Team.class, id);
return team;
}
public void deleteTeam(int id) {
Team team = getTeam(id);
if (team != null){getCurrentSession().delete(team);}
}
@SuppressWarnings("unchecked")
public List<Team> getTeams() {
return getCurrentSession().createQuery("from Team").list();
}
}
这是Initializer:
public class Initializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext)throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebAppConfig.class);
servletContext.addListener(new ContextLoaderListener(ctx));
ctx.setServletContext(servletContext);
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
}
}
这是WebAppConfig:
@Configuration
@ComponentScan("com.sprhib")
@EnableWebMvc
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
public class WebAppConfig {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
@Resource
private Environment env;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
return properties;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
@Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
}
这是团队:
@Entity
@Table(name="teams")
public class Team {
@Id
@GeneratedValue
private Integer id;
private String name;
private Integer rating;
public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Integer getRating() {return rating;}
public void setRating(Integer rating) {this.rating = rating;}
}
这是TeamServiceImpl:
@Service
@Transactional
public class TeamServiceImpl implements TeamService {
@Autowired
private TeamDAO teamDAO;
public void addTeam(Team team) {teamDAO.addTeam(team);}
public void updateTeam(Team team) {teamDAO.updateTeam(team);}
public Team getTeam(int id) {return teamDAO.getTeam(id);}
public void deleteTeam(int id) {teamDAO.deleteTeam(id);}
public List<Team> getTeams() {return teamDAO.getTeams();}
}
如果我应该设置JAVA_OPTS变量以允许类卸载,并增加内存大小,我如何在运行tomcat 7的Windows 7中这样做?
我的感觉是我需要创建一个Windows系统变量,然后可能在命令行上运行一些东西。但是什么?以下是我的开始:
JAVA_OPTS="-XX:MaxPermSize=128M -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -Xms256m -Xmx512m"
答案 0 :(得分:5)
如果要在Windows上更改tomcat实例的JAVA_OPTS
,则需要通常在catalina.bat
中编辑文件TOMCAT_BASE/bin/catalina.bat
。
但是,我会调整你指定的选项。首先,如果您指定-XX:+CMSClassUnloadingEnabled
,则不需要-XX:+CMSPermGenSweepingEnabled
。
其次,要使-XX:+CMSClassUnloadingEnabled
产生任何效果,您还必须指定-XX:+UseConcMarkSweepGC
。
因此,总而言之,编辑TOMCAT_BASE/bin/catalina.bat
并在脚本开头的大rem
语句块下(第99行的某处),添加以下行:
set JAVA_OPTS=-XX:MaxPermSize=128M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -Xms256m -Xmx512m
请记住,如果您需要更多的PermGen空间,请将MaxPermSize
增加到更高的值,但不使用垃圾收集选项(UseConcMarkSweepGC
和CMSClassUnloadingEnabled
),您只需延长不可避免的java.lang.OutOfMemoryError: PermGen space
希望有所帮助
答案 1 :(得分:0)
您的应用程序实际上可能没有内存泄漏。当您多次重新部署应用程序时,服务器出现问题,最终会导致内存不足问题。不幸的是,此时你所能做的就是重启所有内容,你的应用程序运行正常。
看一下this question,它可以帮助你增加Java的可用内存,这样你就可以在遇到这个问题之前工作更长时间。
This question和this answer也可能会有所帮助。