【发布时间】:2013-12-13 15:29:48
【问题描述】:
我最近做了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 关于内存泄漏的信息,例如将大量文件完全加载到内存中而不是使用输入流等。但是当我分析应用程序中的所有代码时,我找不到任何大的变量。我在下面发布代码。请让我知道是否还有其他内容可以帮助您找到问题。
谁能告诉我内存泄漏在哪里?
这里是链接控制器:
@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();
}
}
这里是初始化器:
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"
【问题讨论】:
-
服务器启动时 -XX:MaxPermSize 的值是多少?
-
@benjamin.d 我不知道。我怎样才能知道?
标签: java eclipse spring hibernate memory-leaks